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