NetworkPkg/IScsiDxe: Add IPv6 support condition check.

Base on the request of https://bugzilla.tianocore.org/show_bug.cgi?id=710,
we provide this patch to IPv6 condition check by leveraging AIP Protocol.

Cc: Karunakar P <karunakarp@amiindia.co.in>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Karunakar P <karunakarp@amiindia.co.in>
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
Reviewed-by: Karunakar p <karunakarp@amiindia.co.in>
Reviewed-by: Wu Jiaxin <jiaxin.wu@intel.com>
This commit is contained in:
Jiaxin Wu 2017-10-17 09:48:37 +08:00
parent ed247d86c2
commit 6b08dd6eb8
7 changed files with 159 additions and 4 deletions

View File

@ -3421,6 +3421,9 @@ IScsiFormCallback (
ISCSI_CONFIG_IFR_NVDATA OldIfrNvData; ISCSI_CONFIG_IFR_NVDATA OldIfrNvData;
EFI_STATUS Status; EFI_STATUS Status;
EFI_INPUT_KEY Key; EFI_INPUT_KEY Key;
ISCSI_NIC_INFO *NicInfo;
NicInfo = NULL;
if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) { if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {
// //
@ -3591,6 +3594,21 @@ IScsiFormCallback (
case KEY_IP_MODE: case KEY_IP_MODE:
switch (Value->u8) { switch (Value->u8) {
case IP_MODE_IP6: case IP_MODE_IP6:
NicInfo = IScsiGetNicInfoByIndex (Private->Current->NicIndex);
if(!NicInfo->Ipv6Available) {
//
// Current NIC doesn't Support IPv6, hence use IPv4.
//
IfrNvData->IpMode = IP_MODE_IP4;
CreatePopUp (
EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
&Key,
L"Current NIC doesn't Support IPv6!",
NULL
);
}
case IP_MODE_IP4: case IP_MODE_IP4:
ZeroMem (IfrNvData->LocalIp, sizeof (IfrNvData->LocalIp)); ZeroMem (IfrNvData->LocalIp, sizeof (IfrNvData->LocalIp));
ZeroMem (IfrNvData->SubnetMask, sizeof (IfrNvData->SubnetMask)); ZeroMem (IfrNvData->SubnetMask, sizeof (IfrNvData->SubnetMask));

View File

@ -440,7 +440,7 @@ IScsiStart (
// //
// Record the incoming NIC info. // Record the incoming NIC info.
// //
Status = IScsiAddNic (ControllerHandle); Status = IScsiAddNic (ControllerHandle, Image);
if (EFI_ERROR (Status)) { if (EFI_ERROR (Status)) {
return Status; return Status;
} }

View File

@ -81,6 +81,7 @@ typedef struct {
UINTN BusNumber; UINTN BusNumber;
UINTN DeviceNumber; UINTN DeviceNumber;
UINTN FunctionNumber; UINTN FunctionNumber;
BOOLEAN Ipv6Available;
} ISCSI_NIC_INFO; } ISCSI_NIC_INFO;
typedef struct _ISCSI_PRIVATE_PROTOCOL { typedef struct _ISCSI_PRIVATE_PROTOCOL {

View File

@ -117,6 +117,7 @@
gEfiAuthenticationInfoProtocolGuid gEfiAuthenticationInfoProtocolGuid
## SOMETIMES_CONSUMES ## SOMETIMES_CONSUMES
gEfiAdapterInformationProtocolGuid gEfiAdapterInformationProtocolGuid
gEfiNetworkInterfaceIdentifierProtocolGuid_31 ## SOMETIMES_CONSUMES
[Guids] [Guids]
gEfiEventExitBootServicesGuid ## SOMETIMES_CONSUMES ## Event gEfiEventExitBootServicesGuid ## SOMETIMES_CONSUMES ## Event
@ -125,6 +126,7 @@
gEfiAcpi10TableGuid ## SOMETIMES_CONSUMES ## SystemTable gEfiAcpi10TableGuid ## SOMETIMES_CONSUMES ## SystemTable
gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ## SystemTable gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ## SystemTable
gEfiAdapterInfoNetworkBootGuid ## SOMETIMES_CONSUMES ## UNDEFINED gEfiAdapterInfoNetworkBootGuid ## SOMETIMES_CONSUMES ## UNDEFINED
gEfiAdapterInfoUndiIpv6SupportGuid ## SOMETIMES_CONSUMES ## GUID
## SOMETIMES_PRODUCES ## Variable:L"AttemptOrder" ## SOMETIMES_PRODUCES ## Variable:L"AttemptOrder"
## SOMETIMES_CONSUMES ## Variable:L"AttemptOrder" ## SOMETIMES_CONSUMES ## Variable:L"AttemptOrder"

View File

@ -39,6 +39,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/IScsiInitiatorName.h> #include <Protocol/IScsiInitiatorName.h>
#include <Protocol/ScsiPassThruExt.h> #include <Protocol/ScsiPassThruExt.h>
#include <Protocol/AdapterInformation.h> #include <Protocol/AdapterInformation.h>
#include <Protocol/NetworkInterfaceIdentifier.h>
#include <Library/HiiLib.h> #include <Library/HiiLib.h>
#include <Library/UefiHiiServicesLib.h> #include <Library/UefiHiiServicesLib.h>

View File

@ -465,10 +465,115 @@ IScsiGenRandom (
} }
/**
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. Record the NIC info in global structure.
@param[in] Controller The handle of the controller. @param[in] Controller The handle of the controller.
@param[in] Image Handle of the image.
@retval EFI_SUCCESS The operation is completed. @retval EFI_SUCCESS The operation is completed.
@retval EFI_OUT_OF_RESOURCES Do not have sufficient resources to finish this @retval EFI_OUT_OF_RESOURCES Do not have sufficient resources to finish this
@ -477,7 +582,8 @@ IScsiGenRandom (
**/ **/
EFI_STATUS EFI_STATUS
IScsiAddNic ( IScsiAddNic (
IN EFI_HANDLE Controller IN EFI_HANDLE Controller,
IN EFI_HANDLE Image
) )
{ {
EFI_STATUS Status; EFI_STATUS Status;
@ -509,6 +615,19 @@ IScsiAddNic (
CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0 && CompareMem (&NicInfo->PermanentAddress, MacAddr.Addr, HwAddressSize) == 0 &&
NicInfo->VlanId == VlanId) { NicInfo->VlanId == VlanId) {
mPrivate->CurrentNic = NicInfo->NicIndex; 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; return EFI_SUCCESS;
} }
@ -531,6 +650,18 @@ IScsiAddNic (
NicInfo->NicIndex = (UINT8) (mPrivate->MaxNic + 1); NicInfo->NicIndex = (UINT8) (mPrivate->MaxNic + 1);
mPrivate->MaxNic = NicInfo->NicIndex; 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. // Get the PCI location.
// //

View File

@ -217,6 +217,7 @@ IScsiGenRandom (
Record the NIC information in a global structure. Record the NIC information in a global structure.
@param[in] Controller The handle of the controller. @param[in] Controller The handle of the controller.
@param[in] Image Handle of the image.
@retval EFI_SUCCESS The operation is completed. @retval EFI_SUCCESS The operation is completed.
@retval EFI_OUT_OF_RESOURCES Do not have sufficient resource to finish this @retval EFI_OUT_OF_RESOURCES Do not have sufficient resource to finish this
@ -225,7 +226,8 @@ IScsiGenRandom (
**/ **/
EFI_STATUS EFI_STATUS
IScsiAddNic ( IScsiAddNic (
IN EFI_HANDLE Controller IN EFI_HANDLE Controller,
IN EFI_HANDLE Image
); );
/** /**