]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/VlanConfigDxe/VlanConfigImpl.c
13b77b2c00e7c4aa56b27608576e1fe10573b827
[mirror_edk2.git] / NetworkPkg / VlanConfigDxe / VlanConfigImpl.c
1 /** @file
2 HII Config Access protocol implementation of VLAN configuration module.
3
4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "VlanConfigImpl.h"
10
11 CHAR16 mVlanStorageName[] = L"VlanNvData";
12 EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting = NULL;
13
14 VLAN_CONFIG_PRIVATE_DATA mVlanConfigPrivateDateTemplate = {
15 VLAN_CONFIG_PRIVATE_DATA_SIGNATURE,
16 {
17 VlanExtractConfig,
18 VlanRouteConfig,
19 VlanCallback
20 }
21 };
22
23 VENDOR_DEVICE_PATH mHiiVendorDevicePathNode = {
24 {
25 HARDWARE_DEVICE_PATH,
26 HW_VENDOR_DP,
27 {
28 (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
29 (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
30 }
31 },
32 VLAN_CONFIG_FORM_SET_GUID
33 };
34
35 /**
36 This function allows a caller to extract the current configuration for one
37 or more named elements from the target driver.
38
39 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
40 @param[in] Request A null-terminated Unicode string in
41 <ConfigRequest> format.
42 @param[out] Progress On return, points to a character in the Request
43 string. Points to the string's null terminator if
44 request was successful. Points to the most recent
45 '&' before the first failing name/value pair (or
46 the beginning of the string if the failure is in
47 the first name/value pair) if the request was not
48 successful.
49 @param[out] Results A null-terminated Unicode string in
50 <ConfigAltResp> format which has all values filled
51 in for the names in the Request string. String to
52 be allocated by the called function.
53
54 @retval EFI_SUCCESS The Results is filled with the requested values.
55 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
56 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
57 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
58 driver.
59
60 **/
61 EFI_STATUS
62 EFIAPI
63 VlanExtractConfig (
64 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
65 IN CONST EFI_STRING Request,
66 OUT EFI_STRING *Progress,
67 OUT EFI_STRING *Results
68 )
69 {
70 EFI_STATUS Status;
71 UINTN BufferSize;
72 VLAN_CONFIGURATION Configuration;
73 VLAN_CONFIG_PRIVATE_DATA *PrivateData;
74 EFI_STRING ConfigRequestHdr;
75 EFI_STRING ConfigRequest;
76 BOOLEAN AllocatedRequest;
77 UINTN Size;
78
79 if ((Progress == NULL) || (Results == NULL)) {
80 return EFI_INVALID_PARAMETER;
81 }
82
83 *Progress = Request;
84 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gVlanConfigFormSetGuid, mVlanStorageName)) {
85 return EFI_NOT_FOUND;
86 }
87
88 ConfigRequestHdr = NULL;
89 ConfigRequest = NULL;
90 AllocatedRequest = FALSE;
91 Size = 0;
92
93 //
94 // Retrieve the pointer to the UEFI HII Config Routing Protocol
95 //
96 if (mHiiConfigRouting == NULL) {
97 gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&mHiiConfigRouting);
98 }
99
100 ASSERT (mHiiConfigRouting != NULL);
101
102 //
103 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
104 //
105 PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This);
106 ZeroMem (&Configuration, sizeof (VLAN_CONFIGURATION));
107 BufferSize = sizeof (Configuration);
108 ConfigRequest = Request;
109 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
110 //
111 // Request has no request element, construct full request string.
112 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
113 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
114 //
115 ConfigRequestHdr = HiiConstructConfigHdr (&gVlanConfigFormSetGuid, mVlanStorageName, PrivateData->DriverHandle);
116 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
117 ConfigRequest = AllocateZeroPool (Size);
118 ASSERT (ConfigRequest != NULL);
119 AllocatedRequest = TRUE;
120 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
121 FreePool (ConfigRequestHdr);
122 }
123
124 Status = mHiiConfigRouting->BlockToConfig (
125 mHiiConfigRouting,
126 ConfigRequest,
127 (UINT8 *)&Configuration,
128 BufferSize,
129 Results,
130 Progress
131 );
132 //
133 // Free the allocated config request string.
134 //
135 if (AllocatedRequest) {
136 FreePool (ConfigRequest);
137 ConfigRequest = NULL;
138 }
139
140 //
141 // Set Progress string to the original request string.
142 //
143 if (Request == NULL) {
144 *Progress = NULL;
145 } else if (StrStr (Request, L"OFFSET") == NULL) {
146 *Progress = Request + StrLen (Request);
147 }
148
149 return Status;
150 }
151
152 /**
153 This function processes the results of changes in configuration.
154
155 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
156 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>
157 format.
158 @param[out] Progress A pointer to a string filled in with the offset of
159 the most recent '&' before the first failing
160 name/value pair (or the beginning of the string if
161 the failure is in the first name/value pair) or
162 the terminating NULL if all was successful.
163
164 @retval EFI_SUCCESS The Results is processed successfully.
165 @retval EFI_INVALID_PARAMETER Configuration is NULL.
166 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
167 driver.
168
169 **/
170 EFI_STATUS
171 EFIAPI
172 VlanRouteConfig (
173 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
174 IN CONST EFI_STRING Configuration,
175 OUT EFI_STRING *Progress
176 )
177 {
178 if ((Configuration == NULL) || (Progress == NULL)) {
179 return EFI_INVALID_PARAMETER;
180 }
181
182 *Progress = Configuration;
183 if (!HiiIsConfigHdrMatch (Configuration, &gVlanConfigFormSetGuid, mVlanStorageName)) {
184 return EFI_NOT_FOUND;
185 }
186
187 *Progress = Configuration + StrLen (Configuration);
188 return EFI_SUCCESS;
189 }
190
191 /**
192 This function processes the results of changes in configuration.
193
194 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
195 @param[in] Action Specifies the type of action taken by the browser.
196 @param[in] QuestionId A unique value which is sent to the original
197 exporting driver so that it can identify the type
198 of data to expect.
199 @param[in] Type The type of value for the question.
200 @param[in] Value A pointer to the data being sent to the original
201 exporting driver.
202 @param[out] ActionRequest On return, points to the action requested by the
203 callback function.
204
205 @retval EFI_SUCCESS The callback successfully handled the action.
206 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
207 variable and its data.
208 @retval EFI_DEVICE_ERROR The variable could not be saved.
209 @retval EFI_UNSUPPORTED The specified Action is not supported by the
210 callback.
211
212 **/
213 EFI_STATUS
214 EFIAPI
215 VlanCallback (
216 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
217 IN EFI_BROWSER_ACTION Action,
218 IN EFI_QUESTION_ID QuestionId,
219 IN UINT8 Type,
220 IN EFI_IFR_TYPE_VALUE *Value,
221 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
222 )
223 {
224 VLAN_CONFIG_PRIVATE_DATA *PrivateData;
225 VLAN_CONFIGURATION *Configuration;
226 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
227 UINTN Index;
228 EFI_HANDLE VlanHandle;
229
230 PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This);
231
232 if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {
233 return EFI_SUCCESS;
234 }
235
236 if ((Action != EFI_BROWSER_ACTION_CHANGED) && (Action != EFI_BROWSER_ACTION_CHANGING)) {
237 //
238 // All other action return unsupported.
239 //
240 return EFI_UNSUPPORTED;
241 }
242
243 //
244 // Get Browser data
245 //
246 Configuration = AllocateZeroPool (sizeof (VLAN_CONFIGURATION));
247 ASSERT (Configuration != NULL);
248 HiiGetBrowserData (&gVlanConfigFormSetGuid, mVlanStorageName, sizeof (VLAN_CONFIGURATION), (UINT8 *)Configuration);
249
250 VlanConfig = PrivateData->VlanConfig;
251
252 if (Action == EFI_BROWSER_ACTION_CHANGED) {
253 switch (QuestionId) {
254 case VLAN_ADD_QUESTION_ID:
255 //
256 // Add a VLAN
257 //
258 VlanConfig->Set (VlanConfig, Configuration->VlanId, Configuration->Priority);
259 VlanUpdateForm (PrivateData);
260
261 //
262 // Connect the newly created VLAN device
263 //
264 VlanHandle = NetLibGetVlanHandle (PrivateData->ControllerHandle, Configuration->VlanId);
265 if (VlanHandle == NULL) {
266 //
267 // There may be no child handle created for VLAN ID 0, connect the parent handle
268 //
269 VlanHandle = PrivateData->ControllerHandle;
270 }
271
272 gBS->ConnectController (VlanHandle, NULL, NULL, TRUE);
273
274 //
275 // Clear UI data
276 //
277 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
278 Configuration->VlanId = 0;
279 Configuration->Priority = 0;
280 break;
281
282 case VLAN_REMOVE_QUESTION_ID:
283 //
284 // Remove VLAN
285 //
286 ASSERT (PrivateData->NumberOfVlan <= MAX_VLAN_NUMBER);
287 for (Index = 0; Index < PrivateData->NumberOfVlan; Index++) {
288 if (Configuration->VlanList[Index] != 0) {
289 //
290 // Checkbox is selected, need remove this VLAN
291 //
292 VlanConfig->Remove (VlanConfig, PrivateData->VlanId[Index]);
293 }
294 }
295
296 VlanUpdateForm (PrivateData);
297 if (PrivateData->NumberOfVlan == 0) {
298 //
299 // No VLAN device now, connect the physical NIC handle.
300 // Note: PrivateData->NumberOfVlan has been updated by VlanUpdateForm()
301 //
302 gBS->ConnectController (PrivateData->ControllerHandle, NULL, NULL, TRUE);
303 }
304
305 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
306 ZeroMem (Configuration->VlanList, MAX_VLAN_NUMBER);
307 break;
308
309 default:
310 break;
311 }
312 } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
313 switch (QuestionId) {
314 case VLAN_UPDATE_QUESTION_ID:
315 //
316 // Update current VLAN list into Form.
317 //
318 VlanUpdateForm (PrivateData);
319 break;
320
321 default:
322 break;
323 }
324 }
325
326 HiiSetBrowserData (&gVlanConfigFormSetGuid, mVlanStorageName, sizeof (VLAN_CONFIGURATION), (UINT8 *)Configuration, NULL);
327 FreePool (Configuration);
328 return EFI_SUCCESS;
329 }
330
331 /**
332 This function update VLAN list in the VLAN configuration Form.
333
334 @param[in, out] PrivateData Points to VLAN configuration private data.
335
336 **/
337 VOID
338 VlanUpdateForm (
339 IN OUT VLAN_CONFIG_PRIVATE_DATA *PrivateData
340 )
341 {
342 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
343 UINT16 NumberOfVlan;
344 UINTN Index;
345 EFI_VLAN_FIND_DATA *VlanData;
346 VOID *StartOpCodeHandle;
347 EFI_IFR_GUID_LABEL *StartLabel;
348 VOID *EndOpCodeHandle;
349 EFI_IFR_GUID_LABEL *EndLabel;
350 CHAR16 *String;
351 CHAR16 VlanStr[30];
352 CHAR16 VlanIdStr[6];
353 UINTN DigitalCount;
354 EFI_STRING_ID StringId;
355
356 //
357 // Find current VLAN configuration
358 //
359 VlanData = NULL;
360 NumberOfVlan = 0;
361 VlanConfig = PrivateData->VlanConfig;
362 VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData);
363
364 //
365 // Update VLAN configuration in PrivateData
366 //
367 if (NumberOfVlan > MAX_VLAN_NUMBER) {
368 NumberOfVlan = MAX_VLAN_NUMBER;
369 }
370
371 PrivateData->NumberOfVlan = NumberOfVlan;
372
373 //
374 // Init OpCode Handle
375 //
376 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
377 ASSERT (StartOpCodeHandle != NULL);
378
379 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
380 ASSERT (EndOpCodeHandle != NULL);
381
382 //
383 // Create Hii Extend Label OpCode as the start opcode
384 //
385 StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
386 StartOpCodeHandle,
387 &gEfiIfrTianoGuid,
388 NULL,
389 sizeof (EFI_IFR_GUID_LABEL)
390 );
391 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
392 StartLabel->Number = LABEL_VLAN_LIST;
393
394 //
395 // Create Hii Extend Label OpCode as the end opcode
396 //
397 EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
398 EndOpCodeHandle,
399 &gEfiIfrTianoGuid,
400 NULL,
401 sizeof (EFI_IFR_GUID_LABEL)
402 );
403 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
404 EndLabel->Number = LABEL_END;
405
406 ZeroMem (PrivateData->VlanId, MAX_VLAN_NUMBER);
407 for (Index = 0; Index < NumberOfVlan; Index++) {
408 String = VlanStr;
409
410 StrCpyS (String, (sizeof (VlanStr) /sizeof (CHAR16)), L" VLAN ID:");
411 String += 10;
412 //
413 // Pad VlanId string up to 4 characters with space
414 //
415 UnicodeValueToStringS (VlanIdStr, sizeof (VlanIdStr), 0, VlanData[Index].VlanId, 5);
416 DigitalCount = StrnLenS (VlanIdStr, ARRAY_SIZE (VlanIdStr));
417 SetMem16 (String, (4 - DigitalCount) * sizeof (CHAR16), L' ');
418 StrCpyS (String + 4 - DigitalCount, (sizeof (VlanStr) /sizeof (CHAR16)) - 10 - (4 - DigitalCount), VlanIdStr);
419 String += 4;
420
421 StrCpyS (String, (sizeof (VlanStr) /sizeof (CHAR16)) - 10 - (4 - DigitalCount) - 4, L", Priority:");
422 String += 11;
423 UnicodeValueToStringS (
424 String,
425 sizeof (VlanStr) - ((UINTN)String - (UINTN)VlanStr),
426 0,
427 VlanData[Index].Priority,
428 4
429 );
430 String += StrnLenS (String, ARRAY_SIZE (VlanStr) - ((UINTN)String - (UINTN)VlanStr) / sizeof (CHAR16));
431 *String = 0;
432
433 StringId = HiiSetString (PrivateData->HiiHandle, 0, VlanStr, NULL);
434 ASSERT (StringId != 0);
435
436 HiiCreateCheckBoxOpCode (
437 StartOpCodeHandle,
438 (EFI_QUESTION_ID)(VLAN_LIST_VAR_OFFSET + Index),
439 VLAN_CONFIGURATION_VARSTORE_ID,
440 (UINT16)(VLAN_LIST_VAR_OFFSET + Index),
441 StringId,
442 STRING_TOKEN (STR_VLAN_VLAN_LIST_HELP),
443 0,
444 0,
445 NULL
446 );
447
448 //
449 // Save VLAN id to private data
450 //
451 PrivateData->VlanId[Index] = VlanData[Index].VlanId;
452 }
453
454 HiiUpdateForm (
455 PrivateData->HiiHandle, // HII handle
456 &gVlanConfigFormSetGuid, // Formset GUID
457 VLAN_CONFIGURATION_FORM_ID, // Form ID
458 StartOpCodeHandle, // Label for where to insert opcodes
459 EndOpCodeHandle // Replace data
460 );
461
462 HiiFreeOpCodeHandle (StartOpCodeHandle);
463 HiiFreeOpCodeHandle (EndOpCodeHandle);
464
465 if (VlanData != NULL) {
466 FreePool (VlanData);
467 }
468 }
469
470 /**
471 This function publish the VLAN configuration Form for a network device. The
472 HII Config Access protocol will be installed on a child handle of the network
473 device.
474
475 @param[in, out] PrivateData Points to VLAN configuration private data.
476
477 @retval EFI_SUCCESS HII Form is installed for this network device.
478 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
479 @retval Others Other errors as indicated.
480
481 **/
482 EFI_STATUS
483 InstallVlanConfigForm (
484 IN OUT VLAN_CONFIG_PRIVATE_DATA *PrivateData
485 )
486 {
487 EFI_STATUS Status;
488 EFI_HII_HANDLE HiiHandle;
489 EFI_HANDLE DriverHandle;
490 CHAR16 Str[26 + sizeof (EFI_MAC_ADDRESS) * 2 + 1];
491 CHAR16 *MacString;
492 EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath;
493 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
494 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
495
496 //
497 // Create child handle and install HII Config Access Protocol
498 //
499 ChildDevicePath = AppendDevicePathNode (
500 PrivateData->ParentDevicePath,
501 (CONST EFI_DEVICE_PATH_PROTOCOL *)&mHiiVendorDevicePathNode
502 );
503 if (ChildDevicePath == NULL) {
504 return EFI_OUT_OF_RESOURCES;
505 }
506
507 PrivateData->ChildDevicePath = ChildDevicePath;
508
509 DriverHandle = NULL;
510 ConfigAccess = &PrivateData->ConfigAccess;
511 Status = gBS->InstallMultipleProtocolInterfaces (
512 &DriverHandle,
513 &gEfiDevicePathProtocolGuid,
514 ChildDevicePath,
515 &gEfiHiiConfigAccessProtocolGuid,
516 ConfigAccess,
517 NULL
518 );
519 if (EFI_ERROR (Status)) {
520 return Status;
521 }
522
523 PrivateData->DriverHandle = DriverHandle;
524
525 //
526 // Establish the parent-child relationship between the new created
527 // child handle and the ControllerHandle.
528 //
529 Status = gBS->OpenProtocol (
530 PrivateData->ControllerHandle,
531 &gEfiVlanConfigProtocolGuid,
532 (VOID **)&VlanConfig,
533 PrivateData->ImageHandle,
534 PrivateData->DriverHandle,
535 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
536 );
537 if (EFI_ERROR (Status)) {
538 return Status;
539 }
540
541 //
542 // Publish the HII package list
543 //
544 HiiHandle = HiiAddPackages (
545 &gVlanConfigFormSetGuid,
546 DriverHandle,
547 VlanConfigDxeStrings,
548 VlanConfigBin,
549 NULL
550 );
551 if (HiiHandle == NULL) {
552 return EFI_OUT_OF_RESOURCES;
553 }
554
555 PrivateData->HiiHandle = HiiHandle;
556
557 //
558 // Update formset title help string.
559 //
560 MacString = NULL;
561 Status = NetLibGetMacString (PrivateData->ControllerHandle, PrivateData->ImageHandle, &MacString);
562 if (EFI_ERROR (Status)) {
563 return Status;
564 }
565
566 PrivateData->MacString = MacString;
567
568 StrCpyS (Str, sizeof (Str) / sizeof (CHAR16), L"VLAN Configuration (MAC:");
569 StrCatS (Str, sizeof (Str) / sizeof (CHAR16), MacString);
570 StrCatS (Str, sizeof (Str) / sizeof (CHAR16), L")");
571 HiiSetString (
572 HiiHandle,
573 STRING_TOKEN (STR_VLAN_FORM_SET_TITLE_HELP),
574 Str,
575 NULL
576 );
577
578 //
579 // Update form title help string.
580 //
581 HiiSetString (
582 HiiHandle,
583 STRING_TOKEN (STR_VLAN_FORM_HELP),
584 Str,
585 NULL
586 );
587
588 return EFI_SUCCESS;
589 }
590
591 /**
592 This function remove the VLAN configuration Form for a network device. The
593 child handle for HII Config Access protocol will be destroyed.
594
595 @param[in, out] PrivateData Points to VLAN configuration private data.
596
597 @retval EFI_SUCCESS HII Form has been uninstalled successfully.
598 @retval Others Other errors as indicated.
599
600 **/
601 EFI_STATUS
602 UninstallVlanConfigForm (
603 IN OUT VLAN_CONFIG_PRIVATE_DATA *PrivateData
604 )
605 {
606 EFI_STATUS Status;
607 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
608
609 //
610 // End the parent-child relationship.
611 //
612 Status = gBS->CloseProtocol (
613 PrivateData->ControllerHandle,
614 &gEfiVlanConfigProtocolGuid,
615 PrivateData->ImageHandle,
616 PrivateData->DriverHandle
617 );
618 if (EFI_ERROR (Status)) {
619 return Status;
620 }
621
622 //
623 // Uninstall HII Config Access Protocol
624 //
625 if (PrivateData->DriverHandle != NULL) {
626 Status = gBS->UninstallMultipleProtocolInterfaces (
627 PrivateData->DriverHandle,
628 &gEfiDevicePathProtocolGuid,
629 PrivateData->ChildDevicePath,
630 &gEfiHiiConfigAccessProtocolGuid,
631 &PrivateData->ConfigAccess,
632 NULL
633 );
634 if (EFI_ERROR (Status)) {
635 gBS->OpenProtocol (
636 PrivateData->ControllerHandle,
637 &gEfiVlanConfigProtocolGuid,
638 (VOID **)&VlanConfig,
639 PrivateData->ImageHandle,
640 PrivateData->DriverHandle,
641 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
642 );
643 return Status;
644 }
645
646 PrivateData->DriverHandle = NULL;
647
648 if (PrivateData->ChildDevicePath != NULL) {
649 FreePool (PrivateData->ChildDevicePath);
650 PrivateData->ChildDevicePath = NULL;
651 }
652 }
653
654 //
655 // Free MAC string
656 //
657 if (PrivateData->MacString != NULL) {
658 FreePool (PrivateData->MacString);
659 PrivateData->MacString = NULL;
660 }
661
662 //
663 // Uninstall HII package list
664 //
665 if (PrivateData->HiiHandle != NULL) {
666 HiiRemovePackages (PrivateData->HiiHandle);
667 PrivateData->HiiHandle = NULL;
668 }
669
670 return EFI_SUCCESS;
671 }