/** @file
  Miscellaneous routines for iSCSI driver.

Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "IScsiImpl.h"

GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8  IScsiHexString[] = "0123456789ABCDEFabcdef";

/**
  Removes (trims) specified leading and trailing characters from a string.

  @param[in, out] Str   Pointer to the null-terminated string to be trimmed.
                        On return, Str will hold the trimmed string.

  @param[in]      CharC Character will be trimmed from str.

**/
VOID
IScsiStrTrim (
  IN OUT CHAR16  *Str,
  IN     CHAR16  CharC
  )
{
  CHAR16  *Pointer1;
  CHAR16  *Pointer2;

  if (*Str == 0) {
    return;
  }

  //
  // Trim off the leading and trailing characters c
  //
  for (Pointer1 = Str; (*Pointer1 != 0) && (*Pointer1 == CharC); Pointer1++) {
  }

  Pointer2 = Str;
  if (Pointer2 == Pointer1) {
    while (*Pointer1 != 0) {
      Pointer2++;
      Pointer1++;
    }
  } else {
    while (*Pointer1 != 0) {
      *Pointer2 = *Pointer1;
      Pointer1++;
      Pointer2++;
    }

    *Pointer2 = 0;
  }

  for (Pointer1 = Str + StrLen (Str) - 1; Pointer1 >= Str && *Pointer1 == CharC; Pointer1--) {
  }

  if (Pointer1 !=  Str + StrLen (Str) - 1) {
    *(Pointer1 + 1) = 0;
  }
}

/**
  Calculate the prefix length of the IPv4 subnet mask.

  @param[in]  SubnetMask The IPv4 subnet mask.

  @return     The prefix length of the subnet mask.
  @retval 0   Other errors as indicated.

**/
UINT8
IScsiGetSubnetMaskPrefixLength (
  IN EFI_IPv4_ADDRESS  *SubnetMask
  )
{
  UINT8   Len;
  UINT32  ReverseMask;

  //
  // The SubnetMask is in network byte order.
  //
  ReverseMask = (SubnetMask->Addr[0] << 24) | (SubnetMask->Addr[1] << 16) | (SubnetMask->Addr[2] << 8) | (SubnetMask->Addr[3]);

  //
  // Reverse it.
  //
  ReverseMask = ~ReverseMask;

  if ((ReverseMask & (ReverseMask + 1)) != 0) {
    return 0;
  }

  Len = 0;

  while (ReverseMask != 0) {
    ReverseMask = ReverseMask >> 1;
    Len++;
  }

  return (UINT8)(32 - Len);
}

/**
  Convert the hexadecimal encoded LUN string into the 64-bit LUN.

  @param[in]   Str             The hexadecimal encoded LUN string.
  @param[out]  Lun             Storage to return the 64-bit LUN.

  @retval EFI_SUCCESS            The 64-bit LUN is stored in Lun.
  @retval EFI_INVALID_PARAMETER  The string is malformatted.

**/
EFI_STATUS
IScsiAsciiStrToLun (
  IN  CHAR8  *Str,
  OUT UINT8  *Lun
  )
{
  UINTN   Index, IndexValue, IndexNum, SizeStr;
  CHAR8   TemStr[2];
  UINT8   TemValue;
  UINT16  Value[4];

  ZeroMem (Lun, 8);
  ZeroMem (TemStr, 2);
  ZeroMem ((UINT8 *)Value, sizeof (Value));
  SizeStr    = AsciiStrLen (Str);
  IndexValue = 0;
  IndexNum   = 0;

  for (Index = 0; Index < SizeStr; Index++) {
    TemStr[0] = Str[Index];
    TemValue  = (UINT8)AsciiStrHexToUint64 (TemStr);
    if ((TemValue == 0) && (TemStr[0] != '0')) {
      if ((TemStr[0] != '-') || (IndexNum == 0)) {
        //
        // Invalid Lun Char.
        //
        return EFI_INVALID_PARAMETER;
      }
    }

    if ((TemValue == 0) && (TemStr[0] == '-')) {
      //
      // Next Lun value.
      //
      if (++IndexValue >= 4) {
        //
        // Max 4 Lun value.
        //
        return EFI_INVALID_PARAMETER;
      }

      //
      // Restart str index for the next lun value.
      //
      IndexNum = 0;
      continue;
    }

    if (++IndexNum > 4) {
      //
      // Each Lun Str can't exceed size 4, because it will be as UINT16 value.
      //
      return EFI_INVALID_PARAMETER;
    }

    //
    // Combine UINT16 value.
    //
    Value[IndexValue] = (UINT16)((Value[IndexValue] << 4) + TemValue);
  }

  for (Index = 0; Index <= IndexValue; Index++) {
    *((UINT16 *)&Lun[Index * 2]) =  HTONS (Value[Index]);
  }

  return EFI_SUCCESS;
}

/**
  Convert the 64-bit LUN into the hexadecimal encoded LUN string.

  @param[in]   Lun The 64-bit LUN.
  @param[out]  Str The storage to return the hexadecimal encoded LUN string.

**/
VOID
IScsiLunToUnicodeStr (
  IN UINT8    *Lun,
  OUT CHAR16  *Str
  )
{
  UINTN   Index;
  CHAR16  *TempStr;

  TempStr = Str;

  for (Index = 0; Index < 4; Index++) {
    if ((Lun[2 * Index] | Lun[2 * Index + 1]) == 0) {
      CopyMem (TempStr, L"0-", sizeof (L"0-"));
    } else {
      TempStr[0] = (CHAR16)IScsiHexString[Lun[2 * Index] >> 4];
      TempStr[1] = (CHAR16)IScsiHexString[Lun[2 * Index] & 0x0F];
      TempStr[2] = (CHAR16)IScsiHexString[Lun[2 * Index + 1] >> 4];
      TempStr[3] = (CHAR16)IScsiHexString[Lun[2 * Index + 1] & 0x0F];
      TempStr[4] = L'-';
      TempStr[5] = 0;

      IScsiStrTrim (TempStr, L'0');
    }

    TempStr += StrLen (TempStr);
  }

  //
  // Remove the last '-'
  //
  ASSERT (StrLen (Str) >= 1);
  Str[StrLen (Str) - 1] = 0;

  for (Index = StrLen (Str) - 1; Index > 1; Index = Index - 2) {
    if ((Str[Index] == L'0') && (Str[Index - 1] == L'-')) {
      Str[Index - 1] = 0;
    } else {
      break;
    }
  }
}

/**
  Convert the formatted IP address into the binary IP address.

  @param[in]   Str               The UNICODE string.
  @param[in]   IpMode            Indicates whether the IP address is v4 or v6.
  @param[out]  Ip                The storage to return the ASCII string.

  @retval EFI_SUCCESS            The binary IP address is returned in Ip.
  @retval EFI_INVALID_PARAMETER  The IP string is malformatted or IpMode is
                                 invalid.

**/
EFI_STATUS
IScsiAsciiStrToIp (
  IN  CHAR8           *Str,
  IN  UINT8           IpMode,
  OUT EFI_IP_ADDRESS  *Ip
  )
{
  EFI_STATUS  Status;

  if ((IpMode == IP_MODE_IP4) || (IpMode == IP_MODE_AUTOCONFIG_IP4)) {
    return NetLibAsciiStrToIp4 (Str, &Ip->v4);
  } else if ((IpMode == IP_MODE_IP6) || (IpMode == IP_MODE_AUTOCONFIG_IP6)) {
    return NetLibAsciiStrToIp6 (Str, &Ip->v6);
  } else if (IpMode == IP_MODE_AUTOCONFIG) {
    Status = NetLibAsciiStrToIp4 (Str, &Ip->v4);
    if (!EFI_ERROR (Status)) {
      return Status;
    }

    return NetLibAsciiStrToIp6 (Str, &Ip->v6);
  }

  return EFI_INVALID_PARAMETER;
}

/**
  Convert the mac address into a hexadecimal encoded "-" separated string.

  @param[in]  Mac     The mac address.
  @param[in]  Len     Length in bytes of the mac address.
  @param[in]  VlanId  VLAN ID of the network device.
  @param[out] Str     The storage to return the mac string.

**/
VOID
IScsiMacAddrToStr (
  IN  EFI_MAC_ADDRESS  *Mac,
  IN  UINT32           Len,
  IN  UINT16           VlanId,
  OUT CHAR16           *Str
  )
{
  UINT32  Index;
  CHAR16  *String;

  for (Index = 0; Index < Len; Index++) {
    Str[3 * Index]     = (CHAR16)IScsiHexString[(Mac->Addr[Index] >> 4) & 0x0F];
    Str[3 * Index + 1] = (CHAR16)IScsiHexString[Mac->Addr[Index] & 0x0F];
    Str[3 * Index + 2] = L':';
  }

  String = &Str[3 * Index - 1];
  if (VlanId != 0) {
    String += UnicodeSPrint (String, 6 * sizeof (CHAR16), L"\\%04x", (UINTN)VlanId);
  }

  *String = L'\0';
}

/**
  Convert the binary encoded buffer into a hexadecimal encoded string.

  @param[in]       BinBuffer   The buffer containing the binary data.
  @param[in]       BinLength   Length of the binary buffer.
  @param[in, out]  HexStr      Pointer to the string.
  @param[in, out]  HexLength   The length of the string.

  @retval EFI_SUCCESS          The binary data is converted to the hexadecimal string
                               and the length of the string is updated.
  @retval EFI_BUFFER_TOO_SMALL The string is too small.
  @retval EFI_BAD_BUFFER_SIZE  BinLength is too large for hex encoding.
  @retval EFI_INVALID_PARAMETER The IP string is malformatted.

**/
EFI_STATUS
IScsiBinToHex (
  IN     UINT8   *BinBuffer,
  IN     UINT32  BinLength,
  IN OUT CHAR8   *HexStr,
  IN OUT UINT32  *HexLength
  )
{
  UINT32  HexLengthMin;
  UINT32  HexLengthProvided;
  UINT32  Index;

  if ((HexStr == NULL) || (BinBuffer == NULL) || (BinLength == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Safely calculate: HexLengthMin := BinLength * 2 + 3.
  //
  if (RETURN_ERROR (SafeUint32Mult (BinLength, 2, &HexLengthMin)) ||
      RETURN_ERROR (SafeUint32Add (HexLengthMin, 3, &HexLengthMin)))
  {
    return EFI_BAD_BUFFER_SIZE;
  }

  HexLengthProvided = *HexLength;
  *HexLength        = HexLengthMin;
  if (HexLengthProvided < HexLengthMin) {
    return EFI_BUFFER_TOO_SMALL;
  }

  //
  // Prefix for Hex String.
  //
  HexStr[0] = '0';
  HexStr[1] = 'x';

  for (Index = 0; Index < BinLength; Index++) {
    HexStr[Index * 2 + 2] = IScsiHexString[BinBuffer[Index] >> 4];
    HexStr[Index * 2 + 3] = IScsiHexString[BinBuffer[Index] & 0xf];
  }

  HexStr[Index * 2 + 2] = '\0';

  return EFI_SUCCESS;
}

/**
  Convert the hexadecimal string into a binary encoded buffer.

  @param[in, out]  BinBuffer    The binary buffer.
  @param[in, out]  BinLength    Length of the binary buffer.
  @param[in]       HexStr       The hexadecimal string.

  @retval EFI_SUCCESS           The hexadecimal string is converted into a
                                binary encoded buffer.
  @retval EFI_INVALID_PARAMETER Invalid hex encoding found in HexStr.
  @retval EFI_BAD_BUFFER_SIZE   The length of HexStr is too large for decoding:
                                the decoded size cannot be expressed in
                                BinLength on output.
  @retval EFI_BUFFER_TOO_SMALL  The binary buffer is too small to hold the
                                converted data.
**/
EFI_STATUS
IScsiHexToBin (
  IN OUT UINT8   *BinBuffer,
  IN OUT UINT32  *BinLength,
  IN     CHAR8   *HexStr
  )
{
  UINTN   BinLengthMin;
  UINT32  BinLengthProvided;
  UINTN   Index;
  UINTN   Length;
  UINT8   Digit;
  CHAR8   TemStr[2];

  ZeroMem (TemStr, sizeof (TemStr));

  //
  // Find out how many hex characters the string has.
  //
  if ((HexStr[0] == '0') && ((HexStr[1] == 'x') || (HexStr[1] == 'X'))) {
    HexStr += 2;
  }

  Length = AsciiStrLen (HexStr);

  //
  // Reject an empty hex string; reject a stray nibble.
  //
  if ((Length == 0) || (Length % 2 != 0)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check if the caller provides enough room for the decoded blob.
  //
  BinLengthMin = Length / 2;
  if (BinLengthMin > MAX_UINT32) {
    return EFI_BAD_BUFFER_SIZE;
  }

  BinLengthProvided = *BinLength;
  *BinLength        = (UINT32)BinLengthMin;
  if (BinLengthProvided < BinLengthMin) {
    return EFI_BUFFER_TOO_SMALL;
  }

  for (Index = 0; Index < Length; Index++) {
    TemStr[0] = HexStr[Index];
    Digit     = (UINT8)AsciiStrHexToUint64 (TemStr);
    if ((Digit == 0) && (TemStr[0] != '0')) {
      //
      // Invalid Hex Char.
      //
      return EFI_INVALID_PARAMETER;
    }

    if ((Index & 1) == 0) {
      BinBuffer[Index/2] = Digit;
    } else {
      BinBuffer[Index/2] = (UINT8)((BinBuffer[Index/2] << 4) + Digit);
    }
  }

  return EFI_SUCCESS;
}

/**
  Convert the decimal-constant string or hex-constant string into a numerical value.

  @param[in] Str                    String in decimal or hex.

  @return The numerical value.

**/
UINTN
IScsiNetNtoi (
  IN     CHAR8  *Str
  )
{
  if ((Str[0] == '0') && ((Str[1] == 'x') || (Str[1] == 'X'))) {
    Str += 2;

    return AsciiStrHexToUintn (Str);
  }

  return AsciiStrDecimalToUintn (Str);
}

/**
  Generate random numbers.

  @param[in, out]  Rand       The buffer to contain random numbers.
  @param[in]       RandLength The length of the Rand buffer.

**/
VOID
IScsiGenRandom (
  IN OUT UINT8  *Rand,
  IN     UINTN  RandLength
  )
{
  UINT32  Random;

  while (RandLength > 0) {
    Random  = NET_RANDOM (NetRandomInitSeed ());
    *Rand++ = (UINT8)(Random);
    RandLength--;
  }
}

/**
  Check whether UNDI protocol supports IPv6.

  @param[in]   ControllerHandle    Controller handle.
  @param[in]   Image               Handle of the image.
  @param[out]  Ipv6Support         TRUE if UNDI supports IPv6.

  @retval EFI_SUCCESS            Get the result whether UNDI supports IPv6 by NII or AIP protocol successfully.
  @retval EFI_NOT_FOUND          Don't know whether UNDI supports IPv6 since NII or AIP is not available.

**/
EFI_STATUS
IScsiCheckIpv6Support (
  IN  EFI_HANDLE  ControllerHandle,
  IN  EFI_HANDLE  Image,
  OUT BOOLEAN     *Ipv6Support
  )
{
  EFI_HANDLE                        Handle;
  EFI_ADAPTER_INFORMATION_PROTOCOL  *Aip;
  EFI_STATUS                        Status;
  EFI_GUID                          *InfoTypesBuffer;
  UINTN                             InfoTypeBufferCount;
  UINTN                             TypeIndex;
  BOOLEAN                           Supported;
  VOID                              *InfoBlock;
  UINTN                             InfoBlockSize;

  EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL  *Nii;

  ASSERT (Ipv6Support != NULL);

  //
  // Check whether the UNDI supports IPv6 by NII protocol.
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
                  (VOID **)&Nii,
                  Image,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (Status == EFI_SUCCESS) {
    *Ipv6Support = Nii->Ipv6Supported;
    return EFI_SUCCESS;
  }

  //
  // Get the NIC handle by SNP protocol.
  //
  Handle = NetLibGetSnpHandle (ControllerHandle, NULL);
  if (Handle == NULL) {
    return EFI_NOT_FOUND;
  }

  Aip    = NULL;
  Status = gBS->HandleProtocol (
                  Handle,
                  &gEfiAdapterInformationProtocolGuid,
                  (VOID *)&Aip
                  );
  if (EFI_ERROR (Status) || (Aip == NULL)) {
    return EFI_NOT_FOUND;
  }

  InfoTypesBuffer     = NULL;
  InfoTypeBufferCount = 0;
  Status              = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount);
  if (EFI_ERROR (Status) || (InfoTypesBuffer == NULL)) {
    FreePool (InfoTypesBuffer);
    return EFI_NOT_FOUND;
  }

  Supported = FALSE;
  for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) {
    if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoUndiIpv6SupportGuid)) {
      Supported = TRUE;
      break;
    }
  }

  FreePool (InfoTypesBuffer);
  if (!Supported) {
    return EFI_NOT_FOUND;
  }

  //
  // We now have adapter information block.
  //
  InfoBlock     = NULL;
  InfoBlockSize = 0;
  Status        = Aip->GetInformation (Aip, &gEfiAdapterInfoUndiIpv6SupportGuid, &InfoBlock, &InfoBlockSize);
  if (EFI_ERROR (Status) || (InfoBlock == NULL)) {
    FreePool (InfoBlock);
    return EFI_NOT_FOUND;
  }

  *Ipv6Support = ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *)InfoBlock)->Ipv6Support;
  FreePool (InfoBlock);

  return EFI_SUCCESS;
}

/**
  Record the NIC info in global structure.

  @param[in]  Controller         The handle of the controller.
  @param[in]  Image              Handle of the image.

  @retval EFI_SUCCESS            The operation is completed.
  @retval EFI_OUT_OF_RESOURCES   Do not have sufficient resources to finish this
                                 operation.

**/
EFI_STATUS
IScsiAddNic (
  IN EFI_HANDLE  Controller,
  IN EFI_HANDLE  Image
  )
{
  EFI_STATUS       Status;
  ISCSI_NIC_INFO   *NicInfo;
  LIST_ENTRY       *Entry;
  EFI_MAC_ADDRESS  MacAddr;
  UINTN            HwAddressSize;
  UINT16           VlanId;

  //
  // Get MAC address of this network device.
  //
  Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get VLAN ID of this network device.
  //
  VlanId = NetLibGetVlanId (Controller);

  //
  // Check whether the NIC info already exists. Return directly if so.
  //
  NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
    NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
    if ((NicInfo->HwAddressSize == HwAddressSize) &&
        (CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0) &&
        (NicInfo->VlanId == VlanId))
    {
      mPrivate->CurrentNic = NicInfo->NicIndex;

      //
      // Set IPv6 available flag.
      //
      Status = IScsiCheckIpv6Support (Controller, Image, &NicInfo->Ipv6Available);
      if (EFI_ERROR (Status)) {
        //
        // Fail to get the data whether UNDI supports IPv6.
        // Set default value to TRUE.
        //
        NicInfo->Ipv6Available = TRUE;
      }

      return EFI_SUCCESS;
    }

    if (mPrivate->MaxNic < NicInfo->NicIndex) {
      mPrivate->MaxNic = NicInfo->NicIndex;
    }
  }

  //
  // Record the NIC info in private structure.
  //
  NicInfo = AllocateZeroPool (sizeof (ISCSI_NIC_INFO));
  if (NicInfo == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  CopyMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize);
  NicInfo->HwAddressSize = (UINT32)HwAddressSize;
  NicInfo->VlanId        = VlanId;
  NicInfo->NicIndex      = (UINT8)(mPrivate->MaxNic + 1);
  mPrivate->MaxNic       = NicInfo->NicIndex;

  //
  // Set IPv6 available flag.
  //
  Status = IScsiCheckIpv6Support (Controller, Image, &NicInfo->Ipv6Available);
  if (EFI_ERROR (Status)) {
    //
    // Fail to get the data whether UNDI supports IPv6.
    // Set default value to TRUE.
    //
    NicInfo->Ipv6Available = TRUE;
  }

  //
  // Get the PCI location.
  //
  IScsiGetNICPciLocation (
    Controller,
    &NicInfo->BusNumber,
    &NicInfo->DeviceNumber,
    &NicInfo->FunctionNumber
    );

  InsertTailList (&mPrivate->NicInfoList, &NicInfo->Link);
  mPrivate->NicCount++;

  mPrivate->CurrentNic = NicInfo->NicIndex;
  return EFI_SUCCESS;
}

/**
  Delete the recorded NIC info from global structure. Also delete corresponding
  attempts.

  @param[in]  Controller         The handle of the controller.

  @retval EFI_SUCCESS            The operation is completed.
  @retval EFI_NOT_FOUND          The NIC info to be deleted is not recorded.

**/
EFI_STATUS
IScsiRemoveNic (
  IN EFI_HANDLE  Controller
  )
{
  EFI_STATUS                   Status;
  ISCSI_NIC_INFO               *NicInfo;
  LIST_ENTRY                   *Entry;
  LIST_ENTRY                   *NextEntry;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;
  ISCSI_NIC_INFO               *ThisNic;
  EFI_MAC_ADDRESS              MacAddr;
  UINTN                        HwAddressSize;
  UINT16                       VlanId;

  //
  // Get MAC address of this network device.
  //
  Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get VLAN ID of this network device.
  //
  VlanId = NetLibGetVlanId (Controller);

  //
  // Check whether the NIC information exists.
  //
  ThisNic = NULL;

  NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
    NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
    if ((NicInfo->HwAddressSize == HwAddressSize) &&
        (CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0) &&
        (NicInfo->VlanId == VlanId))
    {
      ThisNic = NicInfo;
      break;
    }
  }

  if (ThisNic == NULL) {
    return EFI_NOT_FOUND;
  }

  mPrivate->CurrentNic = ThisNic->NicIndex;

  RemoveEntryList (&ThisNic->Link);
  FreePool (ThisNic);
  mPrivate->NicCount--;

  //
  // Remove all attempts related to this NIC.
  //
  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mPrivate->AttemptConfigs) {
    AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
    if (AttemptConfigData->NicIndex == mPrivate->CurrentNic) {
      RemoveEntryList (&AttemptConfigData->Link);
      mPrivate->AttemptCount--;

      if ((AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) && (mPrivate->MpioCount > 0)) {
        if (--mPrivate->MpioCount == 0) {
          mPrivate->EnableMpio = FALSE;
        }

        if ((AttemptConfigData->AuthenticationType == ISCSI_AUTH_TYPE_KRB) && (mPrivate->Krb5MpioCount > 0)) {
          mPrivate->Krb5MpioCount--;
        }
      } else if ((AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) && (mPrivate->SinglePathCount > 0)) {
        mPrivate->SinglePathCount--;

        if (mPrivate->ValidSinglePathCount > 0) {
          mPrivate->ValidSinglePathCount--;
        }
      }

      FreePool (AttemptConfigData);
    }
  }

  return EFI_SUCCESS;
}

/**
  Create and initialize the Attempts.

  @param[in]  AttemptNum          The number of Attempts will be created.

  @retval EFI_SUCCESS             The Attempts have been created successfully.
  @retval Others                  Failed to create the Attempt.

**/
EFI_STATUS
IScsiCreateAttempts (
  IN UINTN  AttemptNum
  )
{
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;
  ISCSI_SESSION_CONFIG_NVDATA  *ConfigData;
  UINT8                        *AttemptConfigOrder;
  UINTN                        AttemptConfigOrderSize;
  UINT8                        *AttemptOrderTmp;
  UINTN                        TotalNumber;
  UINT8                        Index;
  EFI_STATUS                   Status;

  for (Index = 1; Index <= AttemptNum; Index++) {
    //
    // Get the initialized attempt order. This is used to essure creating attempts by order.
    //
    AttemptConfigOrder = IScsiGetVariableAndSize (
                           L"InitialAttemptOrder",
                           &gIScsiConfigGuid,
                           &AttemptConfigOrderSize
                           );
    TotalNumber = AttemptConfigOrderSize / sizeof (UINT8);
    if (TotalNumber == AttemptNum) {
      Status = EFI_SUCCESS;
      break;
    }

    TotalNumber++;

    //
    // Append the new created attempt to the end.
    //
    AttemptOrderTmp = AllocateZeroPool (TotalNumber * sizeof (UINT8));
    if (AttemptOrderTmp == NULL) {
      if (AttemptConfigOrder != NULL) {
        FreePool (AttemptConfigOrder);
      }

      return EFI_OUT_OF_RESOURCES;
    }

    if (AttemptConfigOrder != NULL) {
      CopyMem (AttemptOrderTmp, AttemptConfigOrder, AttemptConfigOrderSize);
      FreePool (AttemptConfigOrder);
    }

    AttemptOrderTmp[TotalNumber - 1] = Index;
    AttemptConfigOrder               = AttemptOrderTmp;
    AttemptConfigOrderSize           = TotalNumber * sizeof (UINT8);

    Status = gRT->SetVariable (
                    L"InitialAttemptOrder",
                    &gIScsiConfigGuid,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                    AttemptConfigOrderSize,
                    AttemptConfigOrder
                    );
    FreePool (AttemptConfigOrder);
    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_ERROR,
        "%a: Failed to set 'InitialAttemptOrder' with Guid (%g): "
        "%r\n",
        __func__,
        &gIScsiConfigGuid,
        Status
        ));
      return Status;
    }

    //
    // Create new Attempt
    //
    AttemptConfigData = AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA));
    if (AttemptConfigData == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    ConfigData                    = &AttemptConfigData->SessionConfigData;
    ConfigData->TargetPort        = ISCSI_WELL_KNOWN_PORT;
    ConfigData->ConnectTimeout    = CONNECT_DEFAULT_TIMEOUT;
    ConfigData->ConnectRetryCount = CONNECT_MIN_RETRY;

    AttemptConfigData->AuthenticationType           = ISCSI_AUTH_TYPE_CHAP;
    AttemptConfigData->AuthConfigData.CHAP.CHAPType = ISCSI_CHAP_UNI;
    //
    // Configure the Attempt index and set variable.
    //
    AttemptConfigData->AttemptConfigIndex = Index;

    //
    // Set the attempt name according to the order.
    //
    UnicodeSPrint (
      mPrivate->PortString,
      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
      L"Attempt %d",
      (UINTN)AttemptConfigData->AttemptConfigIndex
      );
    UnicodeStrToAsciiStrS (mPrivate->PortString, AttemptConfigData->AttemptName, ATTEMPT_NAME_SIZE);

    Status = gRT->SetVariable (
                    mPrivate->PortString,
                    &gEfiIScsiInitiatorNameProtocolGuid,
                    ISCSI_CONFIG_VAR_ATTR,
                    sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
                    AttemptConfigData
                    );
    FreePool (AttemptConfigData);
    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_ERROR,
        "%a: Failed to set variable (mPrivate->PortString) with Guid (%g): "
        "%r\n",
        __func__,
        &gEfiIScsiInitiatorNameProtocolGuid,
        Status
        ));
      return Status;
    }
  }

  return EFI_SUCCESS;
}

/**
  Create the iSCSI configuration Keywords for each attempt. You can find the keywords
  defined in the "x-UEFI-ns" namespace (http://www.uefi.org/confignamespace).

  @param[in]  KeywordNum          The number Sets of Keywords will be created.

  @retval EFI_SUCCESS             The operation is completed.
  @retval Others                  Failed to create the Keywords.

**/
EFI_STATUS
IScsiCreateKeywords (
  IN UINTN  KeywordNum
  )
{
  VOID                *StartOpCodeHandle;
  EFI_IFR_GUID_LABEL  *StartLabel;
  VOID                *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL  *EndLabel;
  UINTN               Index;
  EFI_STRING_ID       StringToken;
  CHAR16              StringId[64];
  CHAR16              KeywordId[32];
  EFI_STATUS          Status;

  Status = IScsiCreateOpCode (
             KEYWORD_ENTRY_LABEL,
             &StartOpCodeHandle,
             &StartLabel,
             &EndOpCodeHandle,
             &EndLabel
             );
  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }

  for (Index = 1; Index <= KeywordNum; Index++) {
    //
    // Create iSCSIAttemptName Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_ATTEMPTT_NAME_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIAttemptName:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateStringOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_ATTEMPT_NAME_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_ATTEMPT_NAME_VAR_OFFSET + ATTEMPT_NAME_SIZE * (Index - 1) * sizeof (CHAR16)),
      StringToken,
      StringToken,
      EFI_IFR_FLAG_READ_ONLY,
      0,
      0,
      ATTEMPT_NAME_SIZE,
      NULL
      );

    //
    // Create iSCSIBootEnable Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_MODE_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIBootEnable:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateNumericOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_BOOTENABLE_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_BOOTENABLE_VAR_OFFSET + (Index - 1)),
      StringToken,
      StringToken,
      0,
      EFI_IFR_NUMERIC_SIZE_1,
      0,
      2,
      0,
      NULL
      );

    //
    // Create iSCSIIpAddressType Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_IP_MODE_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIIpAddressType:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateNumericOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_ADDRESS_TYPE_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_ADDRESS_TYPE_VAR_OFFSET + (Index - 1)),
      StringToken,
      StringToken,
      0,
      EFI_IFR_NUMERIC_SIZE_1,
      0,
      2,
      0,
      NULL
      );

    //
    // Create iSCSIConnectRetry Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CONNECT_RETRY_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIConnectRetry:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateNumericOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_CONNECT_RETRY_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_CONNECT_RETRY_VAR_OFFSET + (Index - 1)),
      StringToken,
      StringToken,
      0,
      EFI_IFR_NUMERIC_SIZE_1,
      0,
      16,
      0,
      NULL
      );

    //
    // Create iSCSIConnectTimeout Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CONNECT_TIMEOUT_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIConnectTimeout:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateNumericOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_CONNECT_TIMEOUT_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET + 2 * (Index - 1)),
      StringToken,
      StringToken,
      0,
      EFI_IFR_NUMERIC_SIZE_2,
      CONNECT_MIN_TIMEOUT,
      CONNECT_MAX_TIMEOUT,
      0,
      NULL
      );

    //
    // Create ISID Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_ISID_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIISID:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateStringOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_ISID_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_ISID_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
      StringToken,
      STRING_TOKEN (STR_ISCSI_ISID_HELP),
      0,
      0,
      ISID_CONFIGURABLE_MIN_LEN,
      ISID_CONFIGURABLE_STORAGE,
      NULL
      );

    //
    // Create iSCSIInitiatorInfoViaDHCP Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_VIA_DHCP_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorInfoViaDHCP:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateNumericOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_INITIATOR_VIA_DHCP_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET + (Index - 1)),
      StringToken,
      StringToken,
      0,
      0,
      0,
      1,
      0,
      NULL
      );

    //
    // Create iSCSIInitiatorIpAddress Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_IP_ADDRESS_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorIpAddress:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateStringOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_INITIATOR_IP_ADDRESS_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
      StringToken,
      StringToken,
      0,
      0,
      IP4_MIN_SIZE,
      IP4_STR_MAX_SIZE,
      NULL
      );

    //
    // Create iSCSIInitiatorNetmask Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_NET_MASK_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorNetmask:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateStringOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_INITIATOR_NET_MASK_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
      StringToken,
      StringToken,
      0,
      0,
      IP4_MIN_SIZE,
      IP4_STR_MAX_SIZE,
      NULL
      );

    //
    // Create iSCSIInitiatorGateway Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_INITIATOR_GATE_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIInitiatorGateway:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateStringOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_INITIATOR_GATE_WAY_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
      StringToken,
      StringToken,
      0,
      0,
      IP4_MIN_SIZE,
      IP4_STR_MAX_SIZE,
      NULL
      );

    //
    // Create iSCSITargetInfoViaDHCP Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_VIA_DHCP_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetInfoViaDHCP:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateNumericOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_TARGET_VIA_DHCP_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET + (Index - 1)),
      StringToken,
      StringToken,
      0,
      0,
      0,
      1,
      0,
      NULL
      );

    //
    // Create iSCSITargetTcpPort Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_TCP_PORT_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetTcpPort:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateNumericOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_TARGET_TCP_PORT_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET + 2 * (Index - 1)),
      StringToken,
      StringToken,
      0,
      EFI_IFR_NUMERIC_SIZE_2,
      TARGET_PORT_MIN_NUM,
      TARGET_PORT_MAX_NUM,
      0,
      NULL
      );

    //
    // Create iSCSITargetName Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_NAME_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetName:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateStringOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_TARGET_NAME_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_TARGET_NAME_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
      StringToken,
      StringToken,
      0,
      0,
      ISCSI_NAME_IFR_MIN_SIZE,
      ISCSI_NAME_IFR_MAX_SIZE,
      NULL
      );

    //
    // Create iSCSITargetIpAddress Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_TARGET_IP_ADDRESS_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSITargetIpAddress:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateStringOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_TARGET_IP_ADDRESS_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
      StringToken,
      StringToken,
      0,
      0,
      IP_MIN_SIZE,
      IP_STR_MAX_SIZE,
      NULL
      );

    //
    // Create iSCSILUN Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_LUN_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSILUN:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateStringOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_LUN_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_LUN_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
      StringToken,
      StringToken,
      0,
      0,
      LUN_MIN_SIZE,
      LUN_MAX_SIZE,
      NULL
      );

    //
    // Create iSCSIAuthenticationMethod Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_AUTHENTICATION_METHOD_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIAuthenticationMethod:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateNumericOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_AUTHENTICATION_METHOD_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET + (Index - 1)),
      StringToken,
      StringToken,
      0,
      0,
      0,
      1,
      0,
      NULL
      );

    //
    // Create iSCSIChapType Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHARTYPE_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIChapType:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateNumericOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_CHARTYPE_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_CHARTYPE_VAR_OFFSET + (Index - 1)),
      StringToken,
      StringToken,
      0,
      0,
      0,
      1,
      0,
      NULL
      );

    //
    // Create iSCSIChapUsername Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_USER_NAME_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIChapUsername:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateStringOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_CHAR_USER_NAME_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_CHAR_USER_NAME_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
      StringToken,
      StringToken,
      0,
      0,
      0,
      ISCSI_CHAP_NAME_MAX_LEN,
      NULL
      );

    //
    // Create iSCSIChapSecret Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_SECRET_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIChapSecret:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateStringOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_CHAR_SECRET_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_CHAR_SECRET_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
      StringToken,
      StringToken,
      0,
      0,
      ISCSI_CHAP_SECRET_MIN_LEN,
      ISCSI_CHAP_SECRET_MAX_LEN,
      NULL
      );

    //
    // Create iSCSIReverseChapUsername Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_REVERSE_USER_NAME_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIReverseChapUsername:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateStringOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_CHAR_REVERSE_USER_NAME_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
      StringToken,
      StringToken,
      0,
      0,
      0,
      ISCSI_CHAP_NAME_MAX_LEN,
      NULL
      );

    //
    // Create iSCSIReverseChapSecret Keyword.
    //
    UnicodeSPrint (StringId, sizeof (StringId), L"STR_ISCSI_CHAR_REVERSE_SECRET_PROMPT%d", Index);
    StringToken =  HiiSetString (
                     mCallbackInfo->RegisteredHandle,
                     0,
                     StringId,
                     NULL
                     );
    UnicodeSPrint (KeywordId, sizeof (KeywordId), L"iSCSIReverseChapSecret:%d", Index);
    HiiSetString (mCallbackInfo->RegisteredHandle, StringToken, KeywordId, "x-UEFI-ns");
    HiiCreateStringOpCode (
      StartOpCodeHandle,
      (EFI_QUESTION_ID)(ATTEMPT_CHAR_REVERSE_SECRET_QUESTION_ID + (Index - 1)),
      CONFIGURATION_VARSTORE_ID,
      (UINT16)(ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET + sizeof (KEYWORD_STR) * (Index - 1)),
      StringToken,
      StringToken,
      0,
      0,
      ISCSI_CHAP_SECRET_MIN_LEN,
      ISCSI_CHAP_SECRET_MAX_LEN,
      NULL
      );
  }

  Status = HiiUpdateForm (
             mCallbackInfo->RegisteredHandle, // HII handle
             &gIScsiConfigGuid,               // Formset GUID
             FORMID_ATTEMPT_FORM,             // Form ID
             StartOpCodeHandle,               // Label for where to insert opcodes
             EndOpCodeHandle                  // Replace data
             );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);

  return Status;
}

/**

  Free the attempt configure data variable.

**/
VOID
IScsiCleanAttemptVariable (
  IN   VOID
  )
{
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;
  UINT8                        *AttemptConfigOrder;
  UINTN                        AttemptConfigOrderSize;
  UINTN                        Index;

  //
  // Get the initialized attempt order.
  //
  AttemptConfigOrder = IScsiGetVariableAndSize (
                         L"InitialAttemptOrder",
                         &gIScsiConfigGuid,
                         &AttemptConfigOrderSize
                         );
  if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {
    return;
  }

  for (Index = 1; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
    UnicodeSPrint (
      mPrivate->PortString,
      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
      L"Attempt %d",
      Index
      );

    GetVariable2 (
      mPrivate->PortString,
      &gEfiIScsiInitiatorNameProtocolGuid,
      (VOID **)&AttemptConfigData,
      NULL
      );

    if (AttemptConfigData != NULL) {
      gRT->SetVariable (
             mPrivate->PortString,
             &gEfiIScsiInitiatorNameProtocolGuid,
             0,
             0,
             NULL
             );
    }
  }

  return;
}

/**
  Get the recorded NIC info from global structure by the Index.

  @param[in]  NicIndex          The index indicates the position of NIC info.

  @return Pointer to the NIC info, or NULL if not found.

**/
ISCSI_NIC_INFO *
IScsiGetNicInfoByIndex (
  IN UINT8  NicIndex
  )
{
  LIST_ENTRY      *Entry;
  ISCSI_NIC_INFO  *NicInfo;

  NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
    NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
    if (NicInfo->NicIndex == NicIndex) {
      return NicInfo;
    }
  }

  return NULL;
}

/**
  Get the NIC's PCI location and return it according to the composited
  format defined in iSCSI Boot Firmware Table.

  @param[in]   Controller        The handle of the controller.
  @param[out]  Bus               The bus number.
  @param[out]  Device            The device number.
  @param[out]  Function          The function number.

  @return      The composited representation of the NIC PCI location.

**/
UINT16
IScsiGetNICPciLocation (
  IN EFI_HANDLE  Controller,
  OUT UINTN      *Bus,
  OUT UINTN      *Device,
  OUT UINTN      *Function
  )
{
  EFI_STATUS                Status;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_HANDLE                PciIoHandle;
  EFI_PCI_IO_PROTOCOL       *PciIo;
  UINTN                     Segment;

  Status = gBS->HandleProtocol (
                  Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&DevicePath
                  );
  if (EFI_ERROR (Status)) {
    return 0;
  }

  Status = gBS->LocateDevicePath (
                  &gEfiPciIoProtocolGuid,
                  &DevicePath,
                  &PciIoHandle
                  );
  if (EFI_ERROR (Status)) {
    return 0;
  }

  Status = gBS->HandleProtocol (PciIoHandle, &gEfiPciIoProtocolGuid, (VOID **)&PciIo);
  if (EFI_ERROR (Status)) {
    return 0;
  }

  Status = PciIo->GetLocation (PciIo, &Segment, Bus, Device, Function);
  if (EFI_ERROR (Status)) {
    return 0;
  }

  return (UINT16)((*Bus << 8) | (*Device << 3) | *Function);
}

/**
  Read the EFI variable (VendorGuid/Name) and return a dynamically allocated
  buffer, and the size of the buffer. If failure, return NULL.

  @param[in]   Name                   String part of EFI variable name.
  @param[in]   VendorGuid             GUID part of EFI variable name.
  @param[out]  VariableSize           Returns the size of the EFI variable that was read.

  @return Dynamically allocated memory that contains a copy of the EFI variable.
  @return Caller is responsible freeing the buffer.
  @retval NULL                   Variable was not read.

**/
VOID *
IScsiGetVariableAndSize (
  IN  CHAR16    *Name,
  IN  EFI_GUID  *VendorGuid,
  OUT UINTN     *VariableSize
  )
{
  EFI_STATUS  Status;
  UINTN       BufferSize;
  VOID        *Buffer;

  Buffer = NULL;

  //
  // Pass in a zero size buffer to find the required buffer size.
  //
  BufferSize = 0;
  Status     = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
  if (Status == EFI_BUFFER_TOO_SMALL) {
    //
    // Allocate the buffer to return
    //
    Buffer = AllocateZeroPool (BufferSize);
    if (Buffer == NULL) {
      return NULL;
    }

    //
    // Read variable into the allocated buffer.
    //
    Status = gRT->GetVariable (Name, VendorGuid, NULL, &BufferSize, Buffer);
    if (EFI_ERROR (Status)) {
      BufferSize = 0;
    }
  }

  *VariableSize = BufferSize;
  return Buffer;
}

/**
  Create the iSCSI driver data.

  @param[in] Image      The handle of the driver image.
  @param[in] Controller The handle of the controller.

  @return The iSCSI driver data created.
  @retval NULL Other errors as indicated.

**/
ISCSI_DRIVER_DATA *
IScsiCreateDriverData (
  IN EFI_HANDLE  Image,
  IN EFI_HANDLE  Controller
  )
{
  ISCSI_DRIVER_DATA  *Private;
  EFI_STATUS         Status;

  Private = AllocateZeroPool (sizeof (ISCSI_DRIVER_DATA));
  if (Private == NULL) {
    return NULL;
  }

  Private->Signature  = ISCSI_DRIVER_DATA_SIGNATURE;
  Private->Image      = Image;
  Private->Controller = Controller;
  Private->Session    = NULL;

  //
  // Create an event to be signaled when the BS to RT transition is triggerd so
  // as to abort the iSCSI session.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  IScsiOnExitBootService,
                  Private,
                  &gEfiEventExitBootServicesGuid,
                  &Private->ExitBootServiceEvent
                  );
  if (EFI_ERROR (Status)) {
    FreePool (Private);
    return NULL;
  }

  Private->ExtScsiPassThruHandle = NULL;
  CopyMem (&Private->IScsiExtScsiPassThru, &gIScsiExtScsiPassThruProtocolTemplate, sizeof (EFI_EXT_SCSI_PASS_THRU_PROTOCOL));

  //
  // 0 is designated to the TargetId, so use another value for the AdapterId.
  //
  Private->ExtScsiPassThruMode.AdapterId  = 2;
  Private->ExtScsiPassThruMode.Attributes = EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_PHYSICAL | EFI_EXT_SCSI_PASS_THRU_ATTRIBUTES_LOGICAL;
  Private->ExtScsiPassThruMode.IoAlign    = 4;
  Private->IScsiExtScsiPassThru.Mode      = &Private->ExtScsiPassThruMode;

  return Private;
}

/**
  Clean the iSCSI driver data.

  @param[in]              Private The iSCSI driver data.

  @retval EFI_SUCCESS     The clean operation is successful.
  @retval Others          Other errors as indicated.

**/
EFI_STATUS
IScsiCleanDriverData (
  IN ISCSI_DRIVER_DATA  *Private
  )
{
  EFI_STATUS  Status;

  Status = EFI_SUCCESS;

  if (Private->DevicePath != NULL) {
    Status = gBS->UninstallProtocolInterface (
                    Private->ExtScsiPassThruHandle,
                    &gEfiDevicePathProtocolGuid,
                    Private->DevicePath
                    );
    if (EFI_ERROR (Status)) {
      goto EXIT;
    }

    FreePool (Private->DevicePath);
  }

  if (Private->ExtScsiPassThruHandle != NULL) {
    Status = gBS->UninstallProtocolInterface (
                    Private->ExtScsiPassThruHandle,
                    &gEfiExtScsiPassThruProtocolGuid,
                    &Private->IScsiExtScsiPassThru
                    );
    if (!EFI_ERROR (Status)) {
      mPrivate->OneSessionEstablished = FALSE;
    }
  }

EXIT:
  if (Private->ExitBootServiceEvent != NULL) {
    gBS->CloseEvent (Private->ExitBootServiceEvent);
  }

  mCallbackInfo->Current = NULL;

  FreePool (Private);
  return Status;
}

/**
  Check wheather the Controller handle is configured to use DHCP protocol.

  @param[in]  Controller           The handle of the controller.
  @param[in]  IpVersion            IP_VERSION_4 or IP_VERSION_6.

  @retval TRUE                     The handle of the controller need the Dhcp protocol.
  @retval FALSE                    The handle of the controller does not need the Dhcp protocol.

**/
BOOLEAN
IScsiDhcpIsConfigured (
  IN EFI_HANDLE  Controller,
  IN UINT8       IpVersion
  )
{
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptTmp;
  UINT8                        *AttemptConfigOrder;
  UINTN                        AttemptConfigOrderSize;
  UINTN                        Index;
  EFI_STATUS                   Status;
  EFI_MAC_ADDRESS              MacAddr;
  UINTN                        HwAddressSize;
  UINT16                       VlanId;
  CHAR16                       MacString[ISCSI_MAX_MAC_STRING_LEN];
  CHAR16                       AttemptMacString[ISCSI_MAX_MAC_STRING_LEN];
  CHAR16                       AttemptName[ISCSI_NAME_IFR_MAX_SIZE];

  AttemptConfigOrder = IScsiGetVariableAndSize (
                         L"AttemptOrder",
                         &gIScsiConfigGuid,
                         &AttemptConfigOrderSize
                         );
  if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {
    return FALSE;
  }

  //
  // Get MAC address of this network device.
  //
  Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  //
  // Get VLAN ID of this network device.
  //
  VlanId = NetLibGetVlanId (Controller);
  IScsiMacAddrToStr (&MacAddr, (UINT32)HwAddressSize, VlanId, MacString);

  for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
    UnicodeSPrint (
      AttemptName,
      (UINTN)128,
      L"Attempt %d",
      (UINTN)AttemptConfigOrder[Index]
      );
    Status = GetVariable2 (
               AttemptName,
               &gEfiIScsiInitiatorNameProtocolGuid,
               (VOID **)&AttemptTmp,
               NULL
               );
    if ((AttemptTmp == NULL) || EFI_ERROR (Status)) {
      continue;
    }

    ASSERT (AttemptConfigOrder[Index] == AttemptTmp->AttemptConfigIndex);

    if (AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED) {
      FreePool (AttemptTmp);
      continue;
    }

    if ((AttemptTmp->SessionConfigData.IpMode != IP_MODE_AUTOCONFIG) &&
        (AttemptTmp->SessionConfigData.IpMode != ((IpVersion == IP_VERSION_4) ? IP_MODE_IP4 : IP_MODE_IP6)))
    {
      FreePool (AttemptTmp);
      continue;
    }

    AsciiStrToUnicodeStrS (AttemptTmp->MacString, AttemptMacString, sizeof (AttemptMacString) / sizeof (AttemptMacString[0]));

    if ((AttemptTmp->Actived == ISCSI_ACTIVE_DISABLED) || StrCmp (MacString, AttemptMacString)) {
      continue;
    }

    if ((AttemptTmp->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) ||
        (AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp == TRUE) ||
        (AttemptTmp->SessionConfigData.TargetInfoFromDhcp == TRUE))
    {
      FreePool (AttemptTmp);
      FreePool (AttemptConfigOrder);
      return TRUE;
    }

    FreePool (AttemptTmp);
  }

  FreePool (AttemptConfigOrder);
  return FALSE;
}

/**
  Check whether the Controller handle is configured to use DNS protocol.

  @param[in]  Controller           The handle of the controller.

  @retval TRUE                     The handle of the controller need the Dns protocol.
  @retval FALSE                    The handle of the controller does not need the Dns protocol.

**/
BOOLEAN
IScsiDnsIsConfigured (
  IN EFI_HANDLE  Controller
  )
{
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptTmp;
  UINT8                        *AttemptConfigOrder;
  UINTN                        AttemptConfigOrderSize;
  UINTN                        Index;
  EFI_STATUS                   Status;
  EFI_MAC_ADDRESS              MacAddr;
  UINTN                        HwAddressSize;
  UINT16                       VlanId;
  CHAR16                       AttemptMacString[ISCSI_MAX_MAC_STRING_LEN];
  CHAR16                       MacString[ISCSI_MAX_MAC_STRING_LEN];
  CHAR16                       AttemptName[ISCSI_NAME_IFR_MAX_SIZE];

  AttemptConfigOrder = IScsiGetVariableAndSize (
                         L"AttemptOrder",
                         &gIScsiConfigGuid,
                         &AttemptConfigOrderSize
                         );
  if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {
    return FALSE;
  }

  //
  // Get MAC address of this network device.
  //
  Status = NetLibGetMacAddress (Controller, &MacAddr, &HwAddressSize);
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  //
  // Get VLAN ID of this network device.
  //
  VlanId = NetLibGetVlanId (Controller);
  IScsiMacAddrToStr (&MacAddr, (UINT32)HwAddressSize, VlanId, MacString);

  for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
    UnicodeSPrint (
      AttemptName,
      (UINTN)128,
      L"Attempt %d",
      (UINTN)AttemptConfigOrder[Index]
      );

    Status = GetVariable2 (
               AttemptName,
               &gEfiIScsiInitiatorNameProtocolGuid,
               (VOID **)&AttemptTmp,
               NULL
               );
    if ((AttemptTmp == NULL) || EFI_ERROR (Status)) {
      continue;
    }

    ASSERT (AttemptConfigOrder[Index] == AttemptTmp->AttemptConfigIndex);

    AsciiStrToUnicodeStrS (AttemptTmp->MacString, AttemptMacString, sizeof (AttemptMacString) / sizeof (AttemptMacString[0]));

    if ((AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED) || StrCmp (MacString, AttemptMacString)) {
      FreePool (AttemptTmp);
      continue;
    }

    if (AttemptTmp->SessionConfigData.DnsMode || AttemptTmp->SessionConfigData.TargetInfoFromDhcp) {
      FreePool (AttemptTmp);
      FreePool (AttemptConfigOrder);
      return TRUE;
    } else {
      FreePool (AttemptTmp);
      continue;
    }
  }

  FreePool (AttemptConfigOrder);
  return FALSE;
}

/**
  Get the various configuration data.

  @param[in]  Private   The iSCSI driver data.

  @retval EFI_SUCCESS            The configuration data is retrieved.
  @retval EFI_NOT_FOUND          This iSCSI driver is not configured yet.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate memory.

**/
EFI_STATUS
IScsiGetConfigData (
  IN ISCSI_DRIVER_DATA  *Private
  )
{
  EFI_STATUS                   Status;
  CHAR16                       MacString[ISCSI_MAX_MAC_STRING_LEN];
  CHAR16                       AttemptMacString[ISCSI_MAX_MAC_STRING_LEN];
  UINTN                        Index;
  ISCSI_NIC_INFO               *NicInfo;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptTmp;
  UINT8                        *AttemptConfigOrder;
  UINTN                        AttemptConfigOrderSize;
  CHAR16                       IScsiMode[64];
  CHAR16                       IpMode[64];

  //
  // There should be at least one attempt configured.
  //
  AttemptConfigOrder = IScsiGetVariableAndSize (
                         L"AttemptOrder",
                         &gIScsiConfigGuid,
                         &AttemptConfigOrderSize
                         );
  if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {
    return EFI_NOT_FOUND;
  }

  //
  // Get the iSCSI Initiator Name.
  //
  mPrivate->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;
  Status                        = gIScsiInitiatorName.Get (
                                                        &gIScsiInitiatorName,
                                                        &mPrivate->InitiatorNameLength,
                                                        mPrivate->InitiatorName
                                                        );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get the normal configuration.
  //
  for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
    //
    // Check whether the attempt exists in AttemptConfig.
    //
    AttemptTmp = IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder[Index]);
    if ((AttemptTmp != NULL) && (AttemptTmp->SessionConfigData.Enabled == ISCSI_DISABLED)) {
      continue;
    } else if ((AttemptTmp != NULL) && (AttemptTmp->SessionConfigData.Enabled != ISCSI_DISABLED)) {
      //
      // Check the autoconfig path to see whether it should be retried.
      //
      if ((AttemptTmp->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) &&
          !AttemptTmp->AutoConfigureSuccess)
      {
        if (mPrivate->Ipv6Flag &&
            (AttemptTmp->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6))
        {
          //
          // Autoconfigure for IP6 already attempted but failed. Do not try again.
          //
          continue;
        } else if (!mPrivate->Ipv6Flag &&
                   (AttemptTmp->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4))
        {
          //
          // Autoconfigure for IP4  already attempted but failed. Do not try again.
          //
          continue;
        } else {
          //
          // Try another approach for this autoconfigure path.
          //
          AttemptTmp->AutoConfigureMode =
            (UINT8)(mPrivate->Ipv6Flag ? IP_MODE_AUTOCONFIG_IP6 : IP_MODE_AUTOCONFIG_IP4);
          AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp = TRUE;
          AttemptTmp->SessionConfigData.TargetInfoFromDhcp    = TRUE;
          AttemptTmp->DhcpSuccess                             = FALSE;

          //
          // Get some information from the dhcp server.
          //
          if (!mPrivate->Ipv6Flag) {
            Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptTmp);
            if (!EFI_ERROR (Status)) {
              AttemptTmp->DhcpSuccess = TRUE;
            }
          } else {
            Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptTmp);
            if (!EFI_ERROR (Status)) {
              AttemptTmp->DhcpSuccess = TRUE;
            }
          }

          //
          // Refresh the state of this attempt to NVR.
          //
          UnicodeSPrint (
            mPrivate->PortString,
            (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
            L"Attempt %d",
            (UINTN)AttemptTmp->AttemptConfigIndex
            );

          gRT->SetVariable (
                 mPrivate->PortString,
                 &gEfiIScsiInitiatorNameProtocolGuid,
                 ISCSI_CONFIG_VAR_ATTR,
                 sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
                 AttemptTmp
                 );

          continue;
        }
      } else if (AttemptTmp->SessionConfigData.InitiatorInfoFromDhcp &&
                 !AttemptTmp->ValidPath &&
                 (AttemptTmp->NicIndex == mPrivate->CurrentNic))
      {
        //
        // If the attempt associates with the current NIC, we can
        // get DHCP information for already added, but failed, attempt.
        //
        AttemptTmp->DhcpSuccess = FALSE;
        if (!mPrivate->Ipv6Flag && (AttemptTmp->SessionConfigData.IpMode == IP_MODE_IP4)) {
          Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptTmp);
          if (!EFI_ERROR (Status)) {
            AttemptTmp->DhcpSuccess = TRUE;
          }
        } else if (mPrivate->Ipv6Flag && (AttemptTmp->SessionConfigData.IpMode == IP_MODE_IP6)) {
          Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptTmp);
          if (!EFI_ERROR (Status)) {
            AttemptTmp->DhcpSuccess = TRUE;
          }
        }

        //
        // Refresh the state of this attempt to NVR.
        //
        UnicodeSPrint (
          mPrivate->PortString,
          (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
          L"Attempt %d",
          (UINTN)AttemptTmp->AttemptConfigIndex
          );

        gRT->SetVariable (
               mPrivate->PortString,
               &gEfiIScsiInitiatorNameProtocolGuid,
               ISCSI_CONFIG_VAR_ATTR,
               sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
               AttemptTmp
               );

        continue;
      } else {
        continue;
      }
    }

    //
    // This attempt does not exist in AttemptConfig. Try to add a new one.
    //

    NicInfo = IScsiGetNicInfoByIndex (mPrivate->CurrentNic);
    ASSERT (NicInfo != NULL);
    IScsiMacAddrToStr (&NicInfo->PermanentAddress, NicInfo->HwAddressSize, NicInfo->VlanId, MacString);
    UnicodeSPrint (
      mPrivate->PortString,
      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
      L"Attempt %d",
      (UINTN)AttemptConfigOrder[Index]
      );

    GetVariable2 (
      mPrivate->PortString,
      &gEfiIScsiInitiatorNameProtocolGuid,
      (VOID **)&AttemptConfigData,
      NULL
      );
    AsciiStrToUnicodeStrS (AttemptConfigData->MacString, AttemptMacString, sizeof (AttemptMacString) / sizeof (AttemptMacString[0]));

    if ((AttemptConfigData == NULL) || (AttemptConfigData->Actived == ISCSI_ACTIVE_DISABLED) ||
        StrCmp (MacString, AttemptMacString))
    {
      continue;
    }

    ASSERT (AttemptConfigOrder[Index] == AttemptConfigData->AttemptConfigIndex);

    AttemptConfigData->NicIndex      = NicInfo->NicIndex;
    AttemptConfigData->DhcpSuccess   = FALSE;
    AttemptConfigData->ValidiBFTPath = (BOOLEAN)(mPrivate->EnableMpio ? TRUE : FALSE);
    AttemptConfigData->ValidPath     = FALSE;

    if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) {
      AttemptConfigData->SessionConfigData.InitiatorInfoFromDhcp = TRUE;
      AttemptConfigData->SessionConfigData.TargetInfoFromDhcp    = TRUE;

      AttemptConfigData->AutoConfigureMode =
        (UINT8)(mPrivate->Ipv6Flag ? IP_MODE_AUTOCONFIG_IP6 : IP_MODE_AUTOCONFIG_IP4);
      AttemptConfigData->AutoConfigureSuccess = FALSE;
    }

    //
    // Get some information from dhcp server.
    //
    if ((AttemptConfigData->SessionConfigData.Enabled != ISCSI_DISABLED) &&
        AttemptConfigData->SessionConfigData.InitiatorInfoFromDhcp)
    {
      if (!mPrivate->Ipv6Flag &&
          ((AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP4) ||
           (AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP4)))
      {
        Status = IScsiDoDhcp (Private->Image, Private->Controller, AttemptConfigData);
        if (!EFI_ERROR (Status)) {
          AttemptConfigData->DhcpSuccess = TRUE;
        }
      } else if (mPrivate->Ipv6Flag &&
                 ((AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP6) ||
                  (AttemptConfigData->AutoConfigureMode == IP_MODE_AUTOCONFIG_IP6)))
      {
        Status = IScsiDoDhcp6 (Private->Image, Private->Controller, AttemptConfigData);
        if (!EFI_ERROR (Status)) {
          AttemptConfigData->DhcpSuccess = TRUE;
        }
      }

      //
      // Refresh the state of this attempt to NVR.
      //
      UnicodeSPrint (
        mPrivate->PortString,
        (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
        L"Attempt %d",
        (UINTN)AttemptConfigData->AttemptConfigIndex
        );

      gRT->SetVariable (
             mPrivate->PortString,
             &gEfiIScsiInitiatorNameProtocolGuid,
             ISCSI_CONFIG_VAR_ATTR,
             sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
             AttemptConfigData
             );
    }

    //
    // Update Attempt Help Info.
    //

    if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_DISABLED) {
      UnicodeSPrint (IScsiMode, 64, L"Disabled");
    } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) {
      UnicodeSPrint (IScsiMode, 64, L"Enabled");
    } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {
      UnicodeSPrint (IScsiMode, 64, L"Enabled for MPIO");
    }

    if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP4) {
      UnicodeSPrint (IpMode, 64, L"IP4");
    } else if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_IP6) {
      UnicodeSPrint (IpMode, 64, L"IP6");
    } else if (AttemptConfigData->SessionConfigData.IpMode == IP_MODE_AUTOCONFIG) {
      UnicodeSPrint (IpMode, 64, L"Autoconfigure");
    }

    UnicodeSPrint (
      mPrivate->PortString,
      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
      L"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",
      MacString,
      NicInfo->BusNumber,
      NicInfo->DeviceNumber,
      NicInfo->FunctionNumber,
      IScsiMode,
      IpMode
      );

    AttemptConfigData->AttemptTitleHelpToken = HiiSetString (
                                                 mCallbackInfo->RegisteredHandle,
                                                 0,
                                                 mPrivate->PortString,
                                                 NULL
                                                 );
    if (AttemptConfigData->AttemptTitleHelpToken == 0) {
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Record the attempt in global link list.
    //
    InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);
    mPrivate->AttemptCount++;

    if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {
      mPrivate->MpioCount++;
      mPrivate->EnableMpio = TRUE;

      if (AttemptConfigData->AuthenticationType == ISCSI_AUTH_TYPE_KRB) {
        mPrivate->Krb5MpioCount++;
      }
    } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) {
      mPrivate->SinglePathCount++;
    }
  }

  //
  // Reorder the AttemptConfig by the configured order.
  //
  for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
    AttemptConfigData = IScsiConfigGetAttemptByConfigIndex (AttemptConfigOrder[Index]);
    if (AttemptConfigData == NULL) {
      continue;
    }

    RemoveEntryList (&AttemptConfigData->Link);
    InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);
  }

  //
  // Update the Main Form.
  //
  IScsiConfigUpdateAttempt ();

  FreePool (AttemptConfigOrder);

  //
  //  There should be at least one attempt configuration.
  //
  if (!mPrivate->EnableMpio) {
    if (mPrivate->SinglePathCount == 0) {
      return EFI_NOT_FOUND;
    }

    mPrivate->ValidSinglePathCount = mPrivate->SinglePathCount;
  }

  return EFI_SUCCESS;
}

/**
  Get the device path of the iSCSI tcp connection and update it.

  @param  Session                The iSCSI session.

  @return The updated device path.
  @retval NULL Other errors as indicated.

**/
EFI_DEVICE_PATH_PROTOCOL *
IScsiGetTcpConnDevicePath (
  IN ISCSI_SESSION  *Session
  )
{
  ISCSI_CONNECTION          *Conn;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  EFI_STATUS                Status;
  EFI_DEV_PATH              *DPathNode;
  UINTN                     PathLen;

  if (Session->State != SESSION_STATE_LOGGED_IN) {
    return NULL;
  }

  Conn = NET_LIST_USER_STRUCT_S (
           Session->Conns.ForwardLink,
           ISCSI_CONNECTION,
           Link,
           ISCSI_CONNECTION_SIGNATURE
           );

  Status = gBS->HandleProtocol (
                  Conn->TcpIo.Handle,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&DevicePath
                  );
  if (EFI_ERROR (Status)) {
    return NULL;
  }

  //
  // Duplicate it.
  //
  DevicePath = DuplicateDevicePath (DevicePath);
  if (DevicePath == NULL) {
    return NULL;
  }

  DPathNode = (EFI_DEV_PATH *)DevicePath;

  while (!IsDevicePathEnd (&DPathNode->DevPath)) {
    if (DevicePathType (&DPathNode->DevPath) == MESSAGING_DEVICE_PATH) {
      if (!Conn->Ipv6Flag && (DevicePathSubType (&DPathNode->DevPath) == MSG_IPv4_DP)) {
        DPathNode->Ipv4.LocalPort = 0;

        DPathNode->Ipv4.StaticIpAddress =
          (BOOLEAN)(!Session->ConfigData->SessionConfigData.InitiatorInfoFromDhcp);

        //
        //  Add a judgement here to support previous versions of IPv4_DEVICE_PATH.
        //  In previous versions of IPv4_DEVICE_PATH, GatewayIpAddress and SubnetMask
        //  do not exist.
        //  In new version of IPv4_DEVICE_PATH, structure length is 27.
        //

        PathLen = DevicePathNodeLength (&DPathNode->Ipv4);

        if (PathLen == IP4_NODE_LEN_NEW_VERSIONS) {
          IP4_COPY_ADDRESS (
            &DPathNode->Ipv4.GatewayIpAddress,
            &Session->ConfigData->SessionConfigData.Gateway
            );

          IP4_COPY_ADDRESS (
            &DPathNode->Ipv4.SubnetMask,
            &Session->ConfigData->SessionConfigData.SubnetMask
            );
        }

        break;
      } else if (Conn->Ipv6Flag && (DevicePathSubType (&DPathNode->DevPath) == MSG_IPv6_DP)) {
        DPathNode->Ipv6.LocalPort = 0;

        //
        //  Add a judgement here to support previous versions of IPv6_DEVICE_PATH.
        //  In previous versions of IPv6_DEVICE_PATH, IpAddressOrigin, PrefixLength
        //  and GatewayIpAddress do not exist.
        //  In new version of IPv6_DEVICE_PATH, structure length is 60, while in
        //  old versions, the length is 43.
        //

        PathLen = DevicePathNodeLength (&DPathNode->Ipv6);

        if (PathLen == IP6_NODE_LEN_NEW_VERSIONS ) {
          DPathNode->Ipv6.IpAddressOrigin = 0;
          DPathNode->Ipv6.PrefixLength    = IP6_PREFIX_LENGTH;
          ZeroMem (&DPathNode->Ipv6.GatewayIpAddress, sizeof (EFI_IPv6_ADDRESS));
        } else if (PathLen == IP6_NODE_LEN_OLD_VERSIONS) {
          //
          //  StaticIPAddress is a field in old versions of IPv6_DEVICE_PATH, while ignored in new
          //  version. Set StaticIPAddress through its' offset in old IPv6_DEVICE_PATH.
          //
          *((UINT8 *)(&DPathNode->Ipv6) + IP6_OLD_IPADDRESS_OFFSET) =
            (BOOLEAN)(!Session->ConfigData->SessionConfigData.InitiatorInfoFromDhcp);
        }

        break;
      }
    }

    DPathNode = (EFI_DEV_PATH *)NextDevicePathNode (&DPathNode->DevPath);
  }

  return DevicePath;
}

/**
  Abort the session when the transition from BS to RT is initiated.

  @param[in]   Event  The event signaled.
  @param[in]  Context The iSCSI driver data.

**/
VOID
EFIAPI
IScsiOnExitBootService (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  ISCSI_DRIVER_DATA  *Private;

  Private = (ISCSI_DRIVER_DATA *)Context;

  gBS->CloseEvent (Private->ExitBootServiceEvent);
  Private->ExitBootServiceEvent = NULL;

  if (Private->Session != NULL) {
    IScsiSessionAbort (Private->Session);
  }
}

/**
  Tests whether a controller handle is being managed by IScsi driver.

  This function tests whether the driver specified by DriverBindingHandle is
  currently managing the controller specified by ControllerHandle.  This test
  is performed by evaluating if the protocol specified by ProtocolGuid is
  present on ControllerHandle and is was opened by DriverBindingHandle and Nic
  Device handle with an attribute of EFI_OPEN_PROTOCOL_BY_DRIVER.
  If ProtocolGuid is NULL, then ASSERT().

  @param  ControllerHandle     A handle for a controller to test.
  @param  DriverBindingHandle  Specifies the driver binding handle for the
                               driver.
  @param  ProtocolGuid         Specifies the protocol that the driver specified
                               by DriverBindingHandle opens in its Start()
                               function.

  @retval EFI_SUCCESS          ControllerHandle is managed by the driver
                               specified by DriverBindingHandle.
  @retval EFI_UNSUPPORTED      ControllerHandle is not managed by the driver
                               specified by DriverBindingHandle.

**/
EFI_STATUS
EFIAPI
IScsiTestManagedDevice (
  IN  EFI_HANDLE  ControllerHandle,
  IN  EFI_HANDLE  DriverBindingHandle,
  IN  EFI_GUID    *ProtocolGuid
  )
{
  EFI_STATUS  Status;
  VOID        *ManagedInterface;
  EFI_HANDLE  NicControllerHandle;

  ASSERT (ProtocolGuid != NULL);

  NicControllerHandle = NetLibGetNicHandle (ControllerHandle, ProtocolGuid);
  if (NicControllerHandle == NULL) {
    return EFI_UNSUPPORTED;
  }

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  (EFI_GUID *)ProtocolGuid,
                  &ManagedInterface,
                  DriverBindingHandle,
                  NicControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (!EFI_ERROR (Status)) {
    gBS->CloseProtocol (
           ControllerHandle,
           (EFI_GUID *)ProtocolGuid,
           DriverBindingHandle,
           NicControllerHandle
           );
    return EFI_UNSUPPORTED;
  }

  if (Status != EFI_ALREADY_STARTED) {
    return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}
