Newer
Older
AMI-Aptio-BIOS-Reversed / VlanConfigDxe / VlanConfigDxe.c
@Ajax Dong Ajax Dong 2 days ago 46 KB Init
/** @file
  VlanConfigDxe.c - VLAN Configuration DXE Driver

  This UEFI driver manages VLAN tag configuration on network interfaces
  through the HII Configuration Framework. It implements:
  - Driver Binding Protocol for managing network controller instances
  - VLAN Config Protocol for VLAN tag CRUD operations
  - HII Config Access Protocol for form-based configuration
  - Component Name 2 Protocol for driver identification

  Source layout (from debug strings):
    VlanConfigImpl.c  - HII form logic, callbacks, configuration extraction
    VlanConfigDriver.c - Driver binding, entry point, VLAN protocol ops

  Build path:
    e:\hs\AmiNetworkPkg\UefiNetworkStack\Common\VlanConfigDxe\

  Copyright (c) AMI, Inc. All rights reserved.
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include "VlanConfigDxe.h"

//
// ==========================================================================
// GUID Definitions
// ==========================================================================
//

///
/// VLAN Config Protocol GUID: { B3276D32-41FC-4260-7469-D90FAA23DC4C }
/// Matches the data at 0x7208 in .rdata
///
EFI_GUID gEfiVlanConfigProtocolGuid = {
  0xB3276D32, 0x41FC, 0x4260, { 0x74, 0x69, 0xD9, 0x0F, 0xAA, 0x23, 0xDC, 0x4C }
};

///
/// Managed Network Protocol GUID: { C1539892-9836-5822-AB31-A01843B41A4D }
/// (as used in VlanConfigDriverBindingSupported)
///
EFI_GUID gEfiManagedNetworkProtocolGuid = {
  0xC1539892, 0x9836, 0x5822, { 0xAB, 0x31, 0xA0, 0x18, 0x43, 0xB4, 0x1A, 0x4D }
};

///
/// Device Path Protocol GUID: { 09576E91-6D3F-11D2-8E39-00A0C969723B }
/// (standard UEFI Device Path Protocol GUID)
///
EFI_GUID gEfiDevicePathProtocolGuid = {
  0x09576E91, 0x6D3F, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }
};

//
// Simple Network Protocol GUID: { A19832B9-AC25-11D3-9A2D-0090273FC14D }
// (standard UEFI SNP GUID)
//
EFI_GUID gEfiSimpleNetworkProtocolGuid = {
  0xA19832B9, 0xAC25, 0x11D3, { 0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }
};

//
// HII Protocol GUIDS (standard UEFI)
//
EFI_GUID gEfiHiiStringProtocolGuid = {
  0x0FD96974, 0x23AA, 0x4CDC, { 0xB9, 0xCB, 0x98, 0xD1, 0x77, 0x50, 0x32, 0x2A }
};

EFI_GUID gEfiHiiDatabaseProtocolGuid = {
  0xEF9FC172, 0xA1B2, 0x4693, { 0xB3, 0x27, 0x6D, 0x32, 0xFC, 0x41, 0x60, 0x42 }
};

EFI_GUID gEfiHiiConfigRoutingProtocolGuid = {
  0x587E72D7, 0xCC50, 0x4F79, { 0x82, 0x09, 0xCA, 0x29, 0x1F, 0xC1, 0xA1, 0x0F }
};

EFI_GUID gEfiHiiConfigAccessProtocolGuid = {
  0x5B1B31A1, 0x9562, 0x11D2, { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }
};

EFI_GUID gEfiComponentName2ProtocolGuid = {
  0x6A7A5CFF, 0xE8D9, 0x4F70, { 0xBA, 0xDA, 0x75, 0xAB, 0x30, 0x25, 0xCE, 0x14 }
};

EFI_GUID gEfiDriverBindingProtocolGuid = {
  0x18A031AB, 0xB443, 0x4D1A, { 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71 }
};

//
// ==========================================================================
// Global Variables
// ==========================================================================
//

///
/// Image handle (global)
///
EFI_HANDLE  gImageHandle = NULL;
EFI_SYSTEM_TABLE   *gST = NULL;
EFI_BOOT_SERVICES  *gBS = NULL;
EFI_RUNTIME_SERVICES *gRT = NULL;

///
/// HII Config Routing Protocol handle
///
EFI_HII_CONFIG_ROUTING_PROTOCOL  *gHiiConfigRouting = NULL;

///
/// HII Database Protocol handle
///
EFI_HII_DATABASE_PROTOCOL  *gHiiDatabase = NULL;

///
/// HII String Protocol handle
///
EFI_HII_STRING_PROTOCOL  *gHiiString = NULL;

///
/// HII Config Access Protocol handle (lazy init)
///
EFI_HII_CONFIG_ACCESS_PROTOCOL  *gHiiConfigAccess = NULL;

///
/// Default zero MAC address (6 bytes)
///
UINT8  mZeroMacAddress[6] = { 0, 0, 0, 0, 0, 0 };

///
/// Driver Binding Protocol instance
///
EFI_DRIVER_BINDING_PROTOCOL  gVlanConfigDriverBinding = {
  VlanConfigDriverBindingSupported,
  VlanConfigDriverBindingStart,
  VlanConfigDriverBindingStop,
  0x10,          // Version
  NULL,          // ImageHandle (filled at entry)
  NULL           // DriverBindingHandle (filled at entry)
};

///
/// Component Name 2 Protocol table
///
EFI_COMPONENT_NAME2_PROTOCOL  gVlanConfigComponentName2 = {
  VlanConfigComponentName2GetDriverName,
  VlanConfigComponentName2GetControllerName,
  (CHAR8 *)"eng;en"
};

///
/// HII Config Access Protocol instance
///
EFI_HII_CONFIG_ACCESS_PROTOCOL  gVlanConfigHiiConfigAccess = {
  VlanConfigExtractConfig,
  VlanConfigRouteConfig,
  VlanConfigCallback
};

///
/// VFR binary and string package references (defined in auto-generated files)
///
extern UINT8  mVlanConfigVfrBin[];
extern EFI_GUID  gVlanConfigFormSetGuid;

//
// ==========================================================================
// Function Prototypes for Local Functions
// ==========================================================================
//

EFI_STATUS
VlanConfigInitPrivateData (
  IN VLAN_CONFIG_PRIVATE_DATA  *Private
  );

VOID
VlanConfigCleanupPrivateData (
  IN VLAN_CONFIG_PRIVATE_DATA  *Private
  );

EFI_STRING
VlanConfigConstructConfigRequest (
  IN VLAN_CONFIG_PRIVATE_DATA  *Private
  );

BOOLEAN
VlanConfigValidateConfigHeader (
  IN EFI_STRING  ConfigHdr
  );

BOOLEAN
VlanConfigCompareConfigStrings (
  IN EFI_STRING  FirstString,
  IN EFI_STRING  SecondString,
  IN EFI_STRING  StartSearchString,
  IN EFI_STRING  StopSearchString
  );

EFI_STATUS
VlanConfigUpdateForm (
  IN VLAN_CONFIG_PRIVATE_DATA  *PrivateData
  );

//
// ==========================================================================
// Library Wrappers
// ==========================================================================
//

/**
  Wrapper for gBS->AllocatePool with zero fill.

  @param[in] AllocationSize  Size in bytes.

  @return Pointer to the allocated buffer, NULL on failure.
**/
VOID *
VlanConfigAllocateZeroPool (
  IN UINTN  AllocationSize
  )
{
  VOID  *Buffer;

  Buffer = NULL;
  if (gBS->AllocatePool (EfiBootServicesData, AllocationSize, &Buffer) != EFI_SUCCESS) {
    return NULL;
  }

  if (AllocationSize > 0) {
    ZeroMem (Buffer, AllocationSize);
  }

  return Buffer;
}

/**
  Wrapper for gBS->FreePool.

  @param[in] Buffer  Pointer to buffer to free.
**/
VOID
VlanConfigFreePool (
  IN VOID  *Buffer
  )
{
  if (Buffer != NULL) {
    gBS->FreePool (Buffer);
  }
}

//
// ==========================================================================
// Module Entry Point
// ==========================================================================
//

/**
  Entry point for the VLAN Config DXE driver.

  Initializes global service pointer tables, locates HII protocol
  interfaces, and installs the Driver Binding Protocol together
  with the Component Name 2 Protocol.

  @param[in] ImageHandle  Image handle of this driver.
  @param[in] SystemTable  Pointer to the EFI System Table.

  @retval EFI_SUCCESS           The driver was initialized.
  @retval EFI_UNSUPPORTED       Required protocols were not found.
  @retval other                 An error occurred during driver installation.
**/
EFI_STATUS
EFIAPI
VlanConfigDxeEntryPoint (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  //
  // Initialize global service pointer tables
  //
  gImageHandle = ImageHandle;
  gST          = SystemTable;
  gBS          = SystemTable->BootServices;
  gRT          = SystemTable->RuntimeServices;

  //
  // Locate HII protocol interfaces (LocateProtocol with 0 registration)
  //
  Status = gBS->LocateProtocol (
                  &gEfiHiiStringProtocolGuid,
                  NULL,
                  (VOID **)&gHiiString
                  );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->LocateProtocol (
                  &gEfiHiiDatabaseProtocolGuid,
                  NULL,
                  (VOID **)&gHiiDatabase
                  );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->LocateProtocol (
                  &gEfiHiiConfigRoutingProtocolGuid,
                  NULL,
                  (VOID **)&gHiiConfigRouting
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Locate HII Config Access Protocol (for NV data storage, optional)
  //
  gBS->LocateProtocol (
         &gEfiHiiConfigAccessProtocolGuid,
         NULL,
         (VOID **)&gHiiConfigAccess
         );

  //
  // Set up driver binding protocol handles
  //
  gVlanConfigDriverBinding.ImageHandle         = ImageHandle;
  gVlanConfigDriverBinding.DriverBindingHandle = ImageHandle;

  //
  // Install the Driver Binding and Component Name 2 protocols
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &gVlanConfigDriverBinding.DriverBindingHandle,
                  &gEfiDriverBindingProtocolGuid,
                  &gVlanConfigDriverBinding,
                  &gEfiComponentName2ProtocolGuid,
                  &gVlanConfigComponentName2,
                  NULL
                  );

  ASSERT_EFI_ERROR (Status);
  return Status;
}

//
// ==========================================================================
// Driver Binding Protocol
// ==========================================================================
//

/**
  Tests whether the driver supports a given controller.

  The driver claims support if:
  1. The controller already has a VLAN Config Protocol installed
     (returns EFI_ACCESS_DENIED to avoid duplicates).
  2. The controller supports the Managed Network Protocol.

  @param[in] This                 Pointer to the driver binding protocol.
  @param[in] ControllerHandle     Handle of the controller to test.
  @param[in] RemainingDevicePath  Optional pointer to the remaining device path.

  @retval EFI_SUCCESS             Supported (ManagedNetwork found).
  @retval EFI_ACCESS_DENIED       VLAN Config already installed.
  @retval EFI_UNSUPPORTED         Controller does not have ManagedNetwork.
**/
EFI_STATUS
EFIAPI
VlanConfigDriverBindingSupported (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                       Status;
  EFI_VLAN_CONFIG_PROTOCOL         *VlanConfig;
  EFI_MANAGED_NETWORK_PROTOCOL     *ManagedNetwork;

  //
  // Check if VLAN Config Protocol already exists on this controller.
  // If so, report ACCESS_DENIED to avoid duplicate binding.
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiVlanConfigProtocolGuid,
                  (VOID **)&VlanConfig,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (!EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           ControllerHandle,
           &gEfiVlanConfigProtocolGuid,
           This->DriverBindingHandle,
           ControllerHandle
           );
    return EFI_ACCESS_DENIED;
  }

  //
  // The controller must have Managed Network Protocol
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiManagedNetworkProtocolGuid,
                  (VOID **)&ManagedNetwork,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (!EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           ControllerHandle,
           &gEfiManagedNetworkProtocolGuid,
           This->DriverBindingHandle,
           ControllerHandle
           );
  }

  return Status;
}

/**
  Starts the driver on a controller.

  Opens Simple Network, Managed Network and Device Path protocols,
  allocates and initializes private context (0x130 bytes), creates
  HII form resources, and installs the VLAN Config Protocol.

  @param[in] This                 Pointer to the driver binding protocol.
  @param[in] ControllerHandle     Handle of the controller to start.
  @param[in] RemainingDevicePath  Optional pointer to the remaining device path.

  @retval EFI_SUCCESS             The driver started successfully.
  @retval EFI_OUT_OF_RESOURCES    Memory allocation failed.
  @retval other                   An error occurred.
**/
EFI_STATUS
EFIAPI
VlanConfigDriverBindingStart (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
  )
{
  EFI_STATUS                       Status;
  VLAN_CONFIG_PRIVATE_DATA         *Private;
  EFI_SIMPLE_NETWORK_PROTOCOL      *SimpleNetwork;
  EFI_MANAGED_NETWORK_PROTOCOL     *ManagedNetwork;
  EFI_DEVICE_PATH_PROTOCOL         *DevicePath;
  UINTN                            HandleCount;

  //
  // Check if VLAN Config Protocol already exists on this controller
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiVlanConfigProtocolGuid,
                  (VOID **)&Private,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (!EFI_ERROR (Status)) {
    return EFI_ACCESS_DENIED;
  }

  //
  // Open Simple Network Protocol on the controller (GET_PROTOCOL)
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiSimpleNetworkProtocolGuid,
                  (VOID **)&SimpleNetwork,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open Managed Network Protocol on the controller (BY_DRIVER)
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiManagedNetworkProtocolGuid,
                  (VOID **)&ManagedNetwork,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open Device Path Protocol on the controller (BY_DRIVER)
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&DevicePath,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           ControllerHandle,
           &gEfiManagedNetworkProtocolGuid,
           This->DriverBindingHandle,
           ControllerHandle
           );
    return Status;
  }

  //
  // Allocate and initialize private data structure (0x130 bytes)
  //
  Private = (VLAN_CONFIG_PRIVATE_DATA *)VlanConfigAllocateZeroPool (sizeof (VLAN_CONFIG_PRIVATE_DATA));
  if (Private == NULL) {
    gBS->CloseProtocol (
           ControllerHandle,
           &gEfiManagedNetworkProtocolGuid,
           This->DriverBindingHandle,
           ControllerHandle
           );
    gBS->CloseProtocol (
           ControllerHandle,
           &gEfiDevicePathProtocolGuid,
           This->DriverBindingHandle,
           ControllerHandle
           );
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Initialize private data fields
  //
  Private->Signature             = VLAN_CONFIG_PRIVATE_DATA_SIGNATURE;
  Private->ControllerHandle      = ControllerHandle;
  Private->ImageHandle           = This->ImageHandle;
  Private->SimpleNetwork         = SimpleNetwork;
  Private->ManagedNetwork        = ManagedNetwork;
  Private->DevicePath            = DevicePath;

  //
  // Initialize VLAN Config Protocol interface
  //
  Private->VlanConfigProtocol.Set    = VlanConfigSet;
  Private->VlanConfigProtocol.Find   = VlanConfigFind;
  Private->VlanConfigProtocol.Remove = VlanConfigRemove;

  //
  // Initialize the driver instance and create HII resources
  //
  Status = VlanConfigInitPrivateData (Private);
  if (EFI_ERROR (Status)) {
    VlanConfigCleanupPrivateData (Private);
    VlanConfigFreePool (Private);
    return Status;
  }

  //
  // Install the VLAN Config Protocol on the controller handle
  //
  Status = gBS->InstallProtocolInterface (
                  &ControllerHandle,
                  &gEfiVlanConfigProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  Private
                  );
  if (EFI_ERROR (Status)) {
    VlanConfigCleanupPrivateData (Private);
    VlanConfigFreePool (Private);
    return Status;
  }

  return EFI_SUCCESS;
}

/**
  Stops the driver on a controller.

  Removes the VLAN Config Protocol, closes protocols opened by the
  driver, frees HII resources and the private data structure.

  @param[in] This                 Pointer to the driver binding protocol.
  @param[in] ControllerHandle     Handle of the controller to stop.
  @param[in] NumberOfChildren     Number of child handles.
  @param[in] ChildHandleBuffer    Array of child handles.

  @retval EFI_SUCCESS  The driver stopped on this controller.
**/
EFI_STATUS
EFIAPI
VlanConfigDriverBindingStop (
  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
  IN EFI_HANDLE                   ControllerHandle,
  IN UINTN                        NumberOfChildren,
  IN EFI_HANDLE                   *ChildHandleBuffer
  )
{
  EFI_STATUS               Status;
  VLAN_CONFIG_PRIVATE_DATA *Private;
  EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;

  //
  // Validate signature and get the private data
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiVlanConfigProtocolGuid,
                  (VOID **)&VlanConfig,
                  This->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Private = CR (VlanConfig, VLAN_CONFIG_PRIVATE_DATA, VlanConfigProtocol,
                VLAN_CONFIG_PRIVATE_DATA_SIGNATURE);

  //
  // Clean up HII resources
  //
  VlanConfigCleanupPrivateData (Private);

  //
  // Uninstall the VLAN Config Protocol
  //
  Status = gBS->UninstallProtocolInterface (
                  ControllerHandle,
                  &gEfiVlanConfigProtocolGuid,
                  Private
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Close protocols opened by this driver
  //
  gBS->CloseProtocol (
         ControllerHandle,
         &gEfiManagedNetworkProtocolGuid,
         This->DriverBindingHandle,
         ControllerHandle
         );

  gBS->CloseProtocol (
         ControllerHandle,
         &gEfiDevicePathProtocolGuid,
         This->DriverBindingHandle,
         ControllerHandle
         );

  VlanConfigFreePool (Private);

  return EFI_SUCCESS;
}

//
// ==========================================================================
// Driver Unload / Image Unload Handler
// ==========================================================================
//

/**
  Unload handler for the VLAN Config DXE driver.

  Enumerates all handles that have the VLAN Config Protocol installed
  and stops the driver on each one, then uninstalls the driver binding
  protocol.

  @param[in] ImageHandle  The driver's image handle.

  @retval EFI_SUCCESS  The driver was unloaded.
**/
EFI_STATUS
EFIAPI
VlanConfigDxeUnload (
  IN EFI_HANDLE  ImageHandle
  )
{
  EFI_STATUS               Status;
  UINTN                    HandleCount;
  EFI_HANDLE               *HandleBuffer;
  EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
  UINTN                    Index;

  //
  // Locate all handles with VLAN Config Protocol
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiVlanConfigProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Stop the driver on each controller
  //
  for (Index = 0; Index < HandleCount; Index++) {
    Status = gBS->OpenProtocol (
                    HandleBuffer[Index],
                    &gEfiVlanConfigProtocolGuid,
                    (VOID **)&VlanConfig,
                    ImageHandle,
                    HandleBuffer[Index],
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (!EFI_ERROR (Status)) {
      VlanConfigDriverBindingStop (
        &gVlanConfigDriverBinding,
        HandleBuffer[Index],
        0,
        NULL
        );
    }
  }

  VlanConfigFreePool (HandleBuffer);

  //
  // Uninstall the driver binding and component name protocols
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  ImageHandle,
                  &gEfiDriverBindingProtocolGuid,
                  &gVlanConfigDriverBinding,
                  &gEfiComponentName2ProtocolGuid,
                  &gVlanConfigComponentName2,
                  NULL
                  );

  return Status;
}

//
// ==========================================================================
// Private Data Initialization and Cleanup
// ==========================================================================
//

/**
  Initializes the VLAN private data structure.

  Creates HII resources: registers the formset with HII database,
  populates the form with current VLAN configuration, and publishes
  the HII Config Access Protocol on the controller handle.

  @param[in] Private  Pointer to the private context.

  @retval EFI_SUCCESS  Initialization succeeded.
  @retval other        An error occurred.
**/
EFI_STATUS
VlanConfigInitPrivateData (
  IN VLAN_CONFIG_PRIVATE_DATA  *Private
  )
{
  EFI_STATUS              Status;
  EFI_MAC_ADDRESS         MacAddress;
  UINTN                   MacSize;
  CHAR16                  MacString[64];
  CHAR16                  VlanConfigString[128];
  CHAR16                  *MacAddressString;
  CHAR16                  *MacStr;

  //
  // Extract current MAC address from SNP's mode data
  //
  MacSize = sizeof (EFI_MAC_ADDRESS);
  CopyMem (&MacAddress, &Private->SimpleNetwork->Mode->CurrentAddress, MacSize);
  MacStr = (CHAR16 *)VlanConfigAllocateZeroPool (64 * sizeof (CHAR16));

  if (MacStr != NULL) {
    UnicodeSPrint (
      MacStr,
      64 * sizeof (CHAR16),
      L"MAC:%02x%02x%02x%02x%02x%02x",
      ((UINT8 *)&MacAddress)[0],
      ((UINT8 *)&MacAddress)[1],
      ((UINT8 *)&MacAddress)[2],
      ((UINT8 *)&MacAddress)[3],
      ((UINT8 *)&MacAddress)[4],
      ((UINT8 *)&MacAddress)[5]
      );
  }

  //
  // Register the formset with HII database
  //
  Private->HiiHandle = (EFI_HII_HANDLE)(UINTN)HiiAddPackages (
                         &gEfiVlanConfigProtocolGuid,
                         Private->ImageHandle,
                         (VOID *)mVlanConfigVfrBin,
                         NULL,
                         NULL
                         );
  if (Private->HiiHandle == NULL) {
    VlanConfigFreePool (MacStr);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Install the HII Config Access Protocol on the controller handle
  //
  Status = gBS->InstallProtocolInterface (
                  &Private->ControllerHandle,
                  &gEfiHiiConfigAccessProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &gVlanConfigHiiConfigAccess
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Build the form title: "VLAN Configuration (MAC:...)"
  //
  if (MacStr != NULL) {
    UnicodeSPrint (
      VlanConfigString,
      sizeof (VlanConfigString),
      L"VLAN Configuration (%s)",
      MacStr
      );

    HiiSetString (Private->HiiHandle, 0, VlanConfigString, NULL);
    VlanConfigFreePool (MacStr);
  }

  //
  // Populate the VLAN list on the form
  //
  Status = VlanConfigUpdateForm (Private);

  return Status;
}

/**
  Cleans up resources associated with a VLAN private context.

  Frees HII resources (packages, strings), closes protocols,
  and zeros out private data fields.

  @param[in] Private  Pointer to the private context.
**/
VOID
VlanConfigCleanupPrivateData (
  IN VLAN_CONFIG_PRIVATE_DATA  *Private
  )
{
  //
  // Remove HII Config Access Protocol from the controller
  //
  if (Private->ControllerHandle != NULL) {
    gBS->CloseProtocol (
           Private->ControllerHandle,
           &gEfiManagedNetworkProtocolGuid,
           Private->ImageHandle,
           Private->ControllerHandle
           );

    gBS->CloseProtocol (
           Private->ControllerHandle,
           &gEfiDevicePathProtocolGuid,
           Private->ImageHandle,
           Private->ControllerHandle
           );
  }

  //
  // Remove HII packages (strings and forms)
  //
  if (Private->HiiHandle != NULL) {
    HiiRemovePackages (Private->HiiHandle);
  }
}

//
// ==========================================================================
// VLAN Config Protocol Implementation
// ==========================================================================
//

/**
  Creates a VLAN tag on the network controller.

  Delegates to the Managed Network Protocol's VlanConfig function.

  @param[in] This       Pointer to the VLAN Config Protocol.
  @param[in] VlanId     VLAN ID (0-4094).
  @param[in] Priority   VLAN priority (0-7).

  @retval EFI_SUCCESS  The VLAN tag was created.
  @retval other        The Managed Network Protocol returned an error.
**/
EFI_STATUS
EFIAPI
VlanConfigSet (
  IN EFI_VLAN_CONFIG_PROTOCOL  *This,
  IN UINT16                    VlanId,
  IN UINT8                     Priority
  )
{
  VLAN_CONFIG_PRIVATE_DATA  *Private;

  Private = CR (This, VLAN_CONFIG_PRIVATE_DATA, VlanConfigProtocol,
                VLAN_CONFIG_PRIVATE_DATA_SIGNATURE);

  return Private->ManagedNetwork->VlanConfig (
                                    Private->ManagedNetwork,
                                    VlanId,
                                    Priority
                                    );
}

/**
  Checks if a VLAN ID exists on the network controller.

  @param[in] This       Pointer to the VLAN Config Protocol.
  @param[in] VlanId     VLAN ID to find.

  @retval EFI_SUCCESS       The VLAN ID exists.
  @retval EFI_NOT_FOUND     The VLAN ID was not found.
**/
EFI_STATUS
EFIAPI
VlanConfigFind (
  IN EFI_VLAN_CONFIG_PROTOCOL  *This,
  IN UINT16                    VlanId
  )
{
  VLAN_CONFIG_PRIVATE_DATA  *Private;

  Private = CR (This, VLAN_CONFIG_PRIVATE_DATA, VlanConfigProtocol,
                VLAN_CONFIG_PRIVATE_DATA_SIGNATURE);

  if (Private->ManagedNetwork != NULL) {
    return Private->ManagedNetwork->VlanConfig (
                                      Private->ManagedNetwork,
                                      VlanId,
                                      0
                                      );
  }

  return EFI_NOT_FOUND;
}

/**
  Removes a VLAN tag from the network controller.

  @param[in] This       Pointer to the VLAN Config Protocol.
  @param[in] VlanId     VLAN ID to remove.

  @retval EFI_SUCCESS  The VLAN tag was removed.
**/
EFI_STATUS
EFIAPI
VlanConfigRemove (
  IN EFI_VLAN_CONFIG_PROTOCOL  *This,
  IN UINT16                    VlanId
  )
{
  VLAN_CONFIG_PRIVATE_DATA  *Private;

  Private = CR (This, VLAN_CONFIG_PRIVATE_DATA, VlanConfigProtocol,
                VLAN_CONFIG_PRIVATE_DATA_SIGNATURE);

  return Private->ManagedNetwork->VlanConfig (
                                    Private->ManagedNetwork,
                                    VlanId,
                                    0
                                    );
}

//
// ==========================================================================
// HII Form Population
// ==========================================================================
//

/**
  Updates the HII form with the current set of VLAN entries.

  Queries the Managed Network driver for installed VLAN tags
  and populates the ordered list in the HII form as text op-codes.

  @param[in] PrivateData  Pointer to the VLAN private context.

  @retval EFI_SUCCESS  Form updated.
**/
EFI_STATUS
VlanConfigUpdateForm (
  IN VLAN_CONFIG_PRIVATE_DATA  *PrivateData
  )
{
  VOID                        *StartOpCodeHandle;
  VOID                        *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL          *StartLabel;
  EFI_IFR_GUID_LABEL          *EndLabel;
  VLAN_CONFIGURATION          *VlanConfig;
  UINTN                       VlanCount;
  UINTN                       Index;
  EFI_STRING_ID               StringId;
  CHAR16                      VlanString[64];
  CHAR16                      PriorityString[32];
  CHAR16                      Padding[64];
  UINTN                       PaddingLen;
  UINTN                       VlanListCount;
  UINT16                      *VlanIdList;

  //
  // Query VLAN list from Managed Network
  // PrivateData->ManagedNetwork->VlanConfig (GET)
  //
  PrivateData->NumberOfVlan = 0;

  //
  // Get current VLAN count and list
  //
  VlanListCount = 0;
  VlanIdList    = NULL;

  //
  // Create op-code handles for the form
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create start label
  //
  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
                                       StartOpCodeHandle,
                                       &gEfiIfrTianoGuid,
                                       NULL,
                                       sizeof (EFI_IFR_GUID_LABEL)
                                       );
  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->LabelNumber  = LABEL_START;

  //
  // Create end label
  //
  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
                                     EndOpCodeHandle,
                                     &gEfiIfrTianoGuid,
                                     NULL,
                                     sizeof (EFI_IFR_GUID_LABEL)
                                     );
  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->LabelNumber  = LABEL_END;

  //
  // Cap VLAN count for form display (max 100)
  //
  VlanCount = PrivateData->NumberOfVlan;
  if (VlanCount > VLAN_MAX_COUNT) {
    VlanCount = VLAN_MAX_COUNT;
  }

  //
  // Build form entries for each existing VLAN
  //
  if (VlanCount > 0) {
    ZeroMem (VlanString, sizeof (VlanString));
    ZeroMem (PriorityString, sizeof (PriorityString));

    for (Index = 0; Index < VlanCount; Index++) {
      //
      // Build string: "  VLAN ID: %d"
      //
      UnicodeSPrint (
        VlanString,
        sizeof (VlanString),
        L"  VLAN ID: %d",
        PrivateData->VlanIdList[Index]
        );

      //
      // Pad to align priority text
      //
      PaddingLen = 2 * (4 - (StrLen (VlanString) - 6));
      SetMem16 (Padding, PaddingLen, 0x0020);  // spaces

      //
      // Build priority sub-string
      //
      UnicodeSPrint (
        PriorityString,
        sizeof (PriorityString),
        L", Priority: %d",
        0   // Priority not stored per-VLAN in min implementation
        );

      //
      // Create new string in HII database
      //
      StringId = HiiSetString (PrivateData->HiiHandle, 0, VlanString, NULL);
      ASSERT (StringId != 0);

      //
      // Create the text op-code for this VLAN entry
      //
      HiiCreateTextOpCode (
        StartOpCodeHandle,
        StringId,
        0,
        0,
        (UINT16)(sizeof (VLAN_CONFIGURATION) - 2 - 2 * (UINT16)Index)
        );
    }
  }

  //
  // Update the form
  //
  HiiUpdateForm (
    PrivateData->HiiHandle,
    &gEfiVlanConfigProtocolGuid,
    VLAN_CONFIG_FORM_ID,
    StartOpCodeHandle,
    EndOpCodeHandle
    );

  //
  // Clean up op-code handles
  //
  if (StartOpCodeHandle != NULL) {
    if (*(UINTN *)StartOpCodeHandle != 0) {
      VlanConfigFreePool (*(VOID **)StartOpCodeHandle);
    }
    VlanConfigFreePool (StartOpCodeHandle);
  }

  if (EndOpCodeHandle != NULL) {
    if (*(UINTN *)EndOpCodeHandle != 0) {
      VlanConfigFreePool (*(VOID **)EndOpCodeHandle);
    }
    VlanConfigFreePool (EndOpCodeHandle);
  }

  return EFI_SUCCESS;
}

//
// ==========================================================================
// HII Config Access Protocol
// ==========================================================================
//

/**
  Extract configuration from the driver's form.

  Builds the config request string and delegates to the HII Config Routing
  protocol for extraction. Supports both initial (Request=NULL) and
  subsequent requests.

  @param[in]  This          Pointer to the HII Config Access Protocol.
  @param[in]  Request       Configuration request string (or NULL for initial).
  @param[out] Progress      Pointer to the progress string.
  @param[out] Results       Pointer to the configuration results.

  @retval EFI_SUCCESS     Configuration extracted successfully.
  @retval EFI_NOT_FOUND   Config request header was invalid.
**/
EFI_STATUS
EFIAPI
VlanConfigExtractConfig (
  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN CONST EFI_STRING                      Request,
  OUT EFI_STRING                           *Progress,
  OUT EFI_STRING                           *Results
  )
{
  VLAN_CONFIG_PRIVATE_DATA  *Private;
  EFI_STATUS                Status;
  EFI_STRING                ConfigRequest;
  BOOLEAN                   AllocatedRequest;

  if (Progress == NULL || Results == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Request;
  *Results  = NULL;

  //
  // Validate the config request string if provided
  //
  if (Request != NULL && !VlanConfigValidateConfigHeader (Request)) {
    return EFI_NOT_FOUND;
  }

  AllocatedRequest = FALSE;

  //
  // If no request string, build a complete request for VLAN_CONFIGURATION_SIZE
  //
  if (Request == NULL || !StrStr (Request, L"OFFSET")) {
    ConfigRequest = VlanConfigConstructConfigRequest (Private);
    AllocatedRequest = TRUE;
  } else {
    ConfigRequest = (EFI_STRING)Request;
  }

  //
  // Ensure HII Config Routing protocol is loaded
  //
  if (gHiiConfigRouting == NULL) {
    gBS->LocateProtocol (
           &gEfiHiiConfigRoutingProtocolGuid,
           NULL,
           (VOID **)&gHiiConfigRouting
           );
    ASSERT (gHiiConfigRouting != NULL);
  }

  //
  // Extract configuration via ConfigRouting
  //
  Private = CR (This, VLAN_CONFIG_PRIVATE_DATA, VlanConfigProtocol,
                VLAN_CONFIG_PRIVATE_DATA_SIGNATURE);

  Status = gHiiConfigRouting->ExtractConfig (
                                gHiiConfigRouting,
                                ConfigRequest,
                                Progress,
                                Results
                                );

  //
  *Progress = Request + 2 * StrLen (Request);

  if (AllocatedRequest) {
    VlanConfigFreePool (ConfigRequest);
  }

  return Status;
}

/**
  Route configuration to the driver's NV storage.
  Validates the config header and advances progress to string end.

  @param[in]  This          Pointer to the HII Config Access Protocol.
  @param[in]  Configuration Configuration string.
  @param[out] Progress      Pointer to the progress string.

  @retval EFI_SUCCESS      Configuration routed successfully.
  @retval EFI_NOT_FOUND    Invalid config header.
**/
EFI_STATUS
EFIAPI
VlanConfigRouteConfig (
  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN CONST EFI_STRING                      Configuration,
  OUT EFI_STRING                           *Progress
  )
{
  if (Configuration == NULL || Progress == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Configuration;

  //
  // Validate the config header
  //
  if (!VlanConfigValidateConfigHeader (Configuration)) {
    return EFI_NOT_FOUND;
  }

  //
  // Route to end for progress reporting
  //
  *Progress = Configuration + 2 * StrLen (Configuration);

  return EFI_SUCCESS;
}

/**
  HII Callback for form actions.

  Handles:
  - REFRESH (QuestionId == 0): Reloads VLAN list from controller
  - CHANGING (Action - 3 <= 1): Refresh on form entry/exit
  - CHANGED QuestionId=0x1000: Create VLAN from form data
  - CHANGED QuestionId=0x2000: Delete selected VLANs
  - CHANGED QuestionId=0x3000: Exit form

  @param[in]  This            Pointer to the HII Config Access Protocol.
  @param[in]  Action          The action to perform.
  @param[in]  QuestionId      The question ID.
  @param[in]  Type            The type of the value.
  @param[in]  Value           The value.
  @param[out] ActionRequest   The action request.

  @retval EFI_SUCCESS      The callback processed.
  @retval EFI_UNSUPPORTED  The action is unsupported.
**/
EFI_STATUS
EFIAPI
VlanConfigCallback (
  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN EFI_BROWSER_ACTION                    Action,
  IN EFI_QUESTION_ID                       QuestionId,
  IN UINT8                                 Type,
  IN EFI_IFR_TYPE_VALUE                    *Value,
  OUT EFI_BROWSER_ACTION_REQUEST           *ActionRequest
  )
{
  VLAN_CONFIG_PRIVATE_DATA  *Private;
  VLAN_CONFIGURATION        *Configuration;
  EFI_STATUS                Status;
  UINTN                     Index;
  UINTN                     VlanCount;

  if (ActionRequest == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  Private = CR (This, VLAN_CONFIG_PRIVATE_DATA, VlanConfigProtocol,
                VLAN_CONFIG_PRIVATE_DATA_SIGNATURE);

  Status = EFI_SUCCESS;

  switch (Action) {
  case EFI_BROWSER_ACTION_RETRIEVE:
    break;

  case EFI_BROWSER_ACTION_CHANGING:
    //
    // Refresh data for the form
    //
    if ((QuestionId == 0) || (Action - 3 <= 1)) {
      Status = VlanConfigUpdateForm (Private);
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET;
    }
    break;

  case EFI_BROWSER_ACTION_CHANGED:
    //
    // Process the form submission
    //
    Configuration = (VLAN_CONFIGURATION *)Private->VlanConfigProtocol;

    switch (QuestionId) {
    case QUESTION_ID_VLAN_ID:
      //
      // Add a new VLAN - Value contains VLAN ID (u16) and Priority (u8 at +2)
      //
      if (Value != NULL) {
        Status = Private->ManagedNetwork->VlanConfig (
                                            Private->ManagedNetwork,
                                            Value->u16,
                                            *((UINT8 *)Value + 2)
                                            );
        VlanConfigUpdateForm (Private);

        //
        // Clear the form's VLAN ID/Priority fields
        //
        ZeroMem (&Configuration->VlanId, 4);

        //
        // Reset the network interface to apply the change
        //
        Private->SimpleNetwork->Reset (
                                  Private->SimpleNetwork,
                                  FALSE
                                  );

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET;
      }
      break;

    case FORM_ID_VLAN_LIST:
      //
      // Delete VLANs that are marked (checkbox set)
      //
      VlanCount = Private->NumberOfVlan;
      if (VlanCount > VLAN_MAX_COUNT) {
        VlanCount = VLAN_MAX_COUNT;
      }

      for (Index = 0; Index < VlanCount; Index++) {
        if (Configuration->VlanList[Index] != 0) {
          //
          // Delete VLAN by ID
          //
          Private->ManagedNetwork->VlanConfig (
                                     Private->ManagedNetwork,
                                     PrivateData->VlanIdList[Index],
                                     0
                                     );
        }
      }

      Status = VlanConfigUpdateForm (Private);

      if (PrivateData->NumberOfVlan == 0) {
        Private->SimpleNetwork->Reset (
                                  Private->SimpleNetwork,
                                  FALSE
                                  );
        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_RESET;
      }
      break;
    }
    break;

  default:
    Status = EFI_UNSUPPORTED;
    break;
  }

  return Status;
}

//
// ==========================================================================
// Config String Helpers
// ==========================================================================
//

/**
  Validates the format of a configuration request header string.

  Checks that GUID=, &=NAME= and &=PATH= sections match between
  the provided header and a reference built from the driver's GUID.

  @param[in] ConfigHdr  Configuration header string.

  @retval TRUE   The header is valid.
  @retval FALSE  The header is invalid.
**/
BOOLEAN
VlanConfigValidateConfigHeader (
  IN EFI_STRING  ConfigHdr
  )
{
  EFI_STRING  Temp;
  BOOLEAN     Result;

  if (ConfigHdr == NULL) {
    return FALSE;
  }

  Temp = VlanConfigConstructConfigRequest (NULL);
  if (Temp != NULL) {
    //
    // Check GUID= section (between start and L"&NAME=")
    //
    Result = VlanConfigCompareConfigStrings (
               ConfigHdr,
               Temp,
               L"GUID=",
               L"&NAME="
               );

    if (Result) {
      //
      // Check &NAME= section (between L"&NAME=" and L"&PATH=")
      //
      Result = VlanConfigCompareConfigStrings (
                 ConfigHdr,
                 Temp,
                 L"&NAME=",
                 L"&PATH="
                 );
    }

    VlanConfigFreePool (Temp);
    return Result;
  }

  return FALSE;
}

/**
  Compares two config strings between two markers.

  @param[in] FirstString      First configuration string.
  @param[in] SecondString     Second configuration string.
  @param[in] StartSearchString  Start marker.
  @param[in] StopSearchString   Stop marker.

  @retval TRUE   The substrings match.
  @retval FALSE  The substrings do not match.
**/
BOOLEAN
VlanConfigCompareConfigStrings (
  IN EFI_STRING  FirstString,
  IN EFI_STRING  SecondString,
  IN EFI_STRING  StartSearchString,
  IN EFI_STRING  StopSearchString
  )
{
  CHAR16  *FirstStart;
  CHAR16  *FirstStop;
  CHAR16  *SecondStart;
  CHAR16  *SecondStop;
  UINTN   Length;

  FirstStart = StrStr (FirstString, StartSearchString);
  FirstStop  = StrStr (FirstString, StopSearchString);

  SecondStart = StrStr (SecondString, StartSearchString);
  SecondStop  = StrStr (SecondString, StopSearchString);

  if (FirstStart == NULL || SecondStart == NULL ||
      FirstStop == NULL || SecondStop == NULL) {
    return FALSE;
  }

  Length = (FirstStop - FirstStart);

  if ((SecondStop - SecondStart) != Length) {
    return FALSE;
  }

  return (StrnCmp (FirstStart, SecondStart, Length) == 0);
}

/**
  Constructs a configuration request header string.

  Format: GUID=<hex>&NAME=<VlanNvData_hex>&PATH=<device_path_hex>

  @param[in] Private  Pointer to the private context (optional).
                      May be NULL for building a reference header.

  @return Pointer to the allocated config request string,
          or NULL on failure.
**/
EFI_STRING
VlanConfigConstructConfigRequest (
  IN VLAN_CONFIG_PRIVATE_DATA  *Private
  )
{
  EFI_STRING  ConfigString;
  UINTN       DevicePathSize;
  UINT8       *DevicePathBytes;
  UINTN       Index;
  CHAR16      *Buffer;
  UINTN       BufferSize;
  UINTN       MacStringLen;
  CHAR16      *Ptr;
  BOOLEAN     InValue;

  //
  // Build the config string header components:
  // "GUID=...&NAME=VlanNvData&PATH=..."
  //

  //
  // Walk the device path to calculate its total size
  //
  if (Private != NULL && Private->DevicePath != NULL) {
    DevicePathSize = GetDevicePathSize (Private->DevicePath);
  } else {
    DevicePathSize = 0;
  }

  //
  // Allocate the maximum possible header size:
  // GUID (32 hex) + &NAME= + VlanNvData (8 chars as hex) + &PATH= + device path hex
  //
  BufferSize = 2 * (32 + 8 + 2 + 2 * DevicePathSize) + 66;
  Buffer = (CHAR16 *)VlanConfigAllocateZeroPool (BufferSize);

  if (Buffer == NULL) {
    return NULL;
  }

  //
  // Build the GUID= portion from the protocol GUID
  //
  UnicodeSPrint (
    Buffer,
    BufferSize,
    L"GUID=%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x",
    gEfiVlanConfigProtocolGuid.Data1,
    gEfiVlanConfigProtocolGuid.Data2,
    gEfiVlanConfigProtocolGuid.Data3,
    gEfiVlanConfigProtocolGuid.Data4[0],
    gEfiVlanConfigProtocolGuid.Data4[1],
    gEfiVlanConfigProtocolGuid.Data4[2],
    gEfiVlanConfigProtocolGuid.Data4[3],
    gEfiVlanConfigProtocolGuid.Data4[4],
    gEfiVlanConfigProtocolGuid.Data4[5],
    gEfiVlanConfigProtocolGuid.Data4[6],
    gEfiVlanConfigProtocolGuid.Data4[7]
    );

  ConfigString = Buffer + 2 * StrLen (Buffer);

  //
  // Append "&NAME="
  //
  StrCpyS (ConfigString, (BufferSize - (ConfigString - Buffer)) / 2, L"&NAME=");
  ConfigString += 2 * StrLen (ConfigString);

  //
  // Append "VlanNvData" as hex chars
  //
  for (Index = 0; Index < sizeof (L"VlanNvData") / 2 - 1; Index++) {
    *ConfigString++ = L"0123456789ABCDEF"[L"VlanNvData"[Index] >> 4];
    *ConfigString++ = L"0123456789ABCDEF"[L"VlanNvData"[Index] & 0x0F];
  }

  //
  // Append "&PATH="
  //
  StrCpyS (ConfigString, (BufferSize - (ConfigString - Buffer)) / 2, L"&PATH=");
  ConfigString += 2 * StrLen (ConfigString);

  //
  // Append PATH as hex bytes of device path (or empty if none)
  //
  if (Private != NULL && Private->DevicePath != NULL) {
    DevicePathBytes = (UINT8 *)Private->DevicePath;
    for (Index = 0; Index < DevicePathSize; Index++) {
      *ConfigString++ = L"0123456789ABCDEF"[DevicePathBytes[Index] >> 4];
      *ConfigString++ = L"0123456789ABCDEF"[DevicePathBytes[Index] & 0x0F];
    }
  }

  *ConfigString = 0;

  //
  // Convert uppercase hex to lowercase in PATH/NAME sections
  //
  InValue = FALSE;
  for (Ptr = Buffer; *Ptr != 0; Ptr++) {
    if (*Ptr == L'=') {
      InValue = TRUE;
    } else if (*Ptr == L'&') {
      InValue = FALSE;
    } else if (InValue) {
      if (*Ptr >= L'A' && *Ptr <= L'F') {
        *Ptr = (CHAR16)((UINT16)*Ptr + 32);
      }
    }
  }

  return Buffer;
}

//
// ==========================================================================
// Component Name Protocol
// ==========================================================================
//

/**
  Retrieves the driver name.

  @param[in]  This       Pointer to the Component Name 2 Protocol.
  @param[in]  Language   Language code.
  @param[out] DriverName Pointer to the driver name string.

  @retval EFI_SUCCESS  The driver name was returned.
  @retval EFI_UNSUPPORTED  Language not supported.
**/
EFI_STATUS
EFIAPI
VlanConfigComponentName2GetDriverName (
  IN  EFI_COMPONENT_NAME2_PROTOCOL  *This,
  IN  CHAR8                         *Language,
  OUT CHAR16                        **DriverName
  )
{
  if (Language != NULL && Language[0] == 'e' && Language[1] == 'n') {
    *DriverName = L"VLAN Configuration Driver";
    return EFI_SUCCESS;
  }

  return EFI_UNSUPPORTED;
}

/**
  Retrieves the controller name (not supported).

  @param[in]  This             Pointer to the Component Name 2 Protocol.
  @param[in]  ControllerHandle Handle of the controller.
  @param[in]  ChildHandle      Handle of the child (optional).
  @param[in]  Language         Language code.
  @param[out] ControllerName   Pointer to the controller name string.

  @retval EFI_UNSUPPORTED  Controller naming not supported by this driver.
**/
EFI_STATUS
EFIAPI
VlanConfigComponentName2GetControllerName (
  IN  EFI_COMPONENT_NAME2_PROTOCOL  *This,
  IN  EFI_HANDLE                    ControllerHandle,
  IN  EFI_HANDLE                    ChildHandle,
  IN  CHAR8                         *Language,
  OUT CHAR16                        **ControllerName
  )
{
  return EFI_UNSUPPORTED;
}