/** Display VLAN configuration of a network interface. @param[in] Handle Handle of the network interface. @param[in] NicIndex Index of the network interface. **/ VOID ShowNicVlanInfo ( IN EFI_HANDLE Handle, IN UINTN NicIndex ) { CHAR16 *MacStr; EFI_STATUS Status; UINTN Index; EFI_VLAN_CONFIG_PROTOCOL *VlanConfig; UINT16 NumberOfVlan; EFI_VLAN_FIND_DATA *VlanData; VlanConfig = OpenVlanConfigProtocol (Handle); if (VlanConfig == NULL) { return ; } MacStr = NULL; Status = NetLibGetMacString (Handle, mImageHandle, &MacStr); if (EFI_ERROR (Status)) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_MAC_FAIL), mHiiHandle, Status); goto Exit; } ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_ETH_MAC), mHiiHandle, NicIndex, MacStr); Status = VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData); if (EFI_ERROR (Status)) { if (Status == EFI_NOT_FOUND) { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_NO_VLAN), mHiiHandle); } else { ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_VCONFIG_FIND_FAIL), mHiiHandle, Status); } goto Exit; } for (Index = 0; Index < NumberOfVlan; Index++) { ShellPrintHiiEx ( -1, -1, NULL, STRING_TOKEN (STR_VCONFIG_VLAN_DISPLAY), mHiiHandle, VlanData[Index].VlanId, VlanData[Index].Priority ); } FreePool (VlanData); Exit: CloseVlanConfigProtocol (Handle); if (MacStr != NULL) { FreePool (MacStr); } }
/** This function update VLAN list in the VLAN configuration Form. @param[in, out] PrivateData Points to VLAN configuration private data. **/ VOID VlanUpdateForm ( IN OUT VLAN_CONFIG_PRIVATE_DATA *PrivateData ) { EFI_VLAN_CONFIG_PROTOCOL *VlanConfig; UINT16 NumberOfVlan; UINTN Index; EFI_VLAN_FIND_DATA *VlanData; VOID *StartOpCodeHandle; EFI_IFR_GUID_LABEL *StartLabel; VOID *EndOpCodeHandle; EFI_IFR_GUID_LABEL *EndLabel; CHAR16 *String; CHAR16 VlanStr[30]; CHAR16 VlanIdStr[6]; UINTN DigitalCount; EFI_STRING_ID StringId; // // Find current VLAN configuration // VlanData = NULL; NumberOfVlan = 0; VlanConfig = PrivateData->VlanConfig; VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData); // // Update VLAN configuration in PrivateData // if (NumberOfVlan > MAX_VLAN_NUMBER) { NumberOfVlan = MAX_VLAN_NUMBER; } PrivateData->NumberOfVlan = NumberOfVlan; // // Init OpCode Handle // StartOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (StartOpCodeHandle != NULL); EndOpCodeHandle = HiiAllocateOpCodeHandle (); ASSERT (EndOpCodeHandle != NULL); // // Create Hii Extend Label OpCode as the start opcode // StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL) ); StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; StartLabel->Number = LABEL_VLAN_LIST; // // Create Hii Extend Label OpCode as the end opcode // EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL) ); EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; EndLabel->Number = LABEL_END; ZeroMem (PrivateData->VlanId, MAX_VLAN_NUMBER); for (Index = 0; Index < NumberOfVlan; Index++) { String = VlanStr; StrCpy (String, L" VLAN ID:"); String += 10; // // Pad VlanId string up to 4 characters with space // DigitalCount = UnicodeValueToString (VlanIdStr, 0, VlanData[Index].VlanId, 5); SetMem16 (String, (4 - DigitalCount) * sizeof (CHAR16), L' '); StrCpy (String + 4 - DigitalCount, VlanIdStr); String += 4; StrCpy (String, L", Priority:"); String += 11; String += UnicodeValueToString (String, 0, VlanData[Index].Priority, 4); *String = 0; StringId = HiiSetString (PrivateData->HiiHandle, 0, VlanStr, NULL); ASSERT (StringId != 0); HiiCreateCheckBoxOpCode ( StartOpCodeHandle, (EFI_QUESTION_ID) (VLAN_LIST_VAR_OFFSET + Index), VLAN_CONFIGURATION_VARSTORE_ID, (UINT16) (VLAN_LIST_VAR_OFFSET + Index), StringId, STRING_TOKEN (STR_VLAN_VLAN_LIST_HELP), 0, 0, NULL ); // // Save VLAN id to private data // PrivateData->VlanId[Index] = VlanData[Index].VlanId; } HiiUpdateForm ( PrivateData->HiiHandle, // HII handle &gVlanConfigFormSetGuid, // Formset GUID VLAN_CONFIGURATION_FORM_ID, // Form ID StartOpCodeHandle, // Label for where to insert opcodes EndOpCodeHandle // Replace data ); HiiFreeOpCodeHandle (StartOpCodeHandle); HiiFreeOpCodeHandle (EndOpCodeHandle); if (VlanData != NULL) { FreePool (VlanData); } }
/** This function processes the results of changes in configuration. @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. @param[in] Action Specifies the type of action taken by the browser. @param[in] QuestionId A unique value which is sent to the original exporting driver so that it can identify the type of data to expect. @param[in] Type The type of value for the question. @param[in] Value A pointer to the data being sent to the original exporting driver. @param[out] ActionRequest On return, points to the action requested by the callback function. @retval EFI_SUCCESS The callback successfully handled the action. @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. @retval EFI_DEVICE_ERROR The variable could not be saved. @retval EFI_UNSUPPORTED The specified Action is not supported by the callback. **/ EFI_STATUS EFIAPI VlanCallback ( 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 *PrivateData; VLAN_CONFIGURATION *Configuration; EFI_VLAN_CONFIG_PROTOCOL *VlanConfig; UINTN Index; EFI_HANDLE VlanHandle; PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This); if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) { return EFI_SUCCESS; } if ((Action != EFI_BROWSER_ACTION_CHANGED) && (Action != EFI_BROWSER_ACTION_CHANGING)) { // // All other action return unsupported. // return EFI_UNSUPPORTED; } // // Get Browser data // Configuration = AllocateZeroPool (sizeof (VLAN_CONFIGURATION)); ASSERT (Configuration != NULL); HiiGetBrowserData (&gVlanConfigFormSetGuid, mVlanStorageName, sizeof (VLAN_CONFIGURATION), (UINT8 *) Configuration); VlanConfig = PrivateData->VlanConfig; if (Action == EFI_BROWSER_ACTION_CHANGED) { switch (QuestionId) { case VLAN_ADD_QUESTION_ID: // // Add a VLAN // VlanConfig->Set (VlanConfig, Configuration->VlanId, Configuration->Priority); VlanUpdateForm (PrivateData); // // Connect the newly created VLAN device // VlanHandle = NetLibGetVlanHandle (PrivateData->ControllerHandle, Configuration->VlanId); if (VlanHandle == NULL) { // // There may be no child handle created for VLAN ID 0, connect the parent handle // VlanHandle = PrivateData->ControllerHandle; } gBS->ConnectController (VlanHandle, NULL, NULL, TRUE); // // Clear UI data // *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; Configuration->VlanId = 0; Configuration->Priority = 0; break; case VLAN_REMOVE_QUESTION_ID: // // Remove VLAN // ASSERT (PrivateData->NumberOfVlan <= MAX_VLAN_NUMBER); for (Index = 0; Index < PrivateData->NumberOfVlan; Index++) { if (Configuration->VlanList[Index] != 0) { // // Checkbox is selected, need remove this VLAN // VlanConfig->Remove (VlanConfig, PrivateData->VlanId[Index]); } } VlanUpdateForm (PrivateData); if (PrivateData->NumberOfVlan == 0) { // // No VLAN device now, connect the physical NIC handle. // Note: PrivateData->NumberOfVlan has been updated by VlanUpdateForm() // gBS->ConnectController (PrivateData->ControllerHandle, NULL, NULL, TRUE); } *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; ZeroMem (Configuration->VlanList, MAX_VLAN_NUMBER); break; default: break; } } else if (Action == EFI_BROWSER_ACTION_CHANGING) { switch (QuestionId) { case VLAN_UPDATE_QUESTION_ID: // // Update current VLAN list into Form. // VlanUpdateForm (PrivateData); break; default: break; } } HiiSetBrowserData (&gVlanConfigFormSetGuid, mVlanStorageName, sizeof (VLAN_CONFIGURATION), (UINT8 *) Configuration, NULL); FreePool (Configuration); return EFI_SUCCESS; }