2 HII Config Access protocol implementation of VLAN configuration module.
4 Copyright (c) 2009 - 2010, Intel Corporation.<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions
7 of the BSD License which accompanies this distribution. The full
8 text of the license may be found at<BR>
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "VlanConfigImpl.h"
18 EFI_GUID mVlanFormSetGuid
= VLAN_CONFIG_PRIVATE_GUID
;
19 CHAR16 mVlanStorageName
[] = L
"VlanNvData";
20 EFI_HII_CONFIG_ROUTING_PROTOCOL
*mHiiConfigRouting
= NULL
;
22 VLAN_CONFIG_PRIVATE_DATA mVlanConfigPrivateDateTemplate
= {
23 VLAN_CONFIG_PRIVATE_DATA_SIGNATURE
,
31 VENDOR_DEVICE_PATH mHiiVendorDevicePathNode
= {
36 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
37 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
40 VLAN_CONFIG_PRIVATE_GUID
44 This function allows a caller to extract the current configuration for one
45 or more named elements from the target driver.
47 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
48 @param[in] Request A null-terminated Unicode string in
49 <ConfigRequest> format.
50 @param[out] Progress On return, points to a character in the Request
51 string. Points to the string's null terminator if
52 request was successful. Points to the most recent
53 '&' before the first failing name/value pair (or
54 the beginning of the string if the failure is in
55 the first name/value pair) if the request was not
57 @param[out] Results A null-terminated Unicode string in
58 <ConfigAltResp> format which has all values filled
59 in for the names in the Request string. String to
60 be allocated by the called function.
62 @retval EFI_SUCCESS The Results is filled with the requested values.
63 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
64 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
65 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
72 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
73 IN CONST EFI_STRING Request
,
74 OUT EFI_STRING
*Progress
,
75 OUT EFI_STRING
*Results
80 VLAN_CONFIGURATION Configuration
;
82 if (Request
== NULL
) {
83 return EFI_INVALID_PARAMETER
;
87 // Retrieve the pointer to the UEFI HII Config Routing Protocol
89 if (mHiiConfigRouting
== NULL
) {
90 gBS
->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid
, NULL
, (VOID
**) &mHiiConfigRouting
);
92 ASSERT (mHiiConfigRouting
!= NULL
);
95 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
97 ZeroMem (&Configuration
, sizeof (VLAN_CONFIGURATION
));
98 BufferSize
= sizeof (VLAN_CONFIG_PRIVATE_DATA
);
99 Status
= mHiiConfigRouting
->BlockToConfig (
102 (UINT8
*) &Configuration
,
112 This function processes the results of changes in configuration.
114 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
115 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>
117 @param[out] Progress A pointer to a string filled in with the offset of
118 the most recent '&' before the first failing
119 name/value pair (or the beginning of the string if
120 the failure is in the first name/value pair) or
121 the terminating NULL if all was successful.
123 @retval EFI_SUCCESS The Results is processed successfully.
124 @retval EFI_INVALID_PARAMETER Configuration is NULL.
125 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
132 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
133 IN CONST EFI_STRING Configuration
,
134 OUT EFI_STRING
*Progress
137 if (Configuration
== NULL
|| Progress
== NULL
) {
138 return EFI_INVALID_PARAMETER
;
141 *Progress
= Configuration
;
142 if (!HiiIsConfigHdrMatch (Configuration
, &mVlanFormSetGuid
, mVlanStorageName
)) {
143 return EFI_NOT_FOUND
;
146 *Progress
= Configuration
+ StrLen (Configuration
);
151 This function processes the results of changes in configuration.
153 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
154 @param[in] Action Specifies the type of action taken by the browser.
155 @param[in] QuestionId A unique value which is sent to the original
156 exporting driver so that it can identify the type
158 @param[in] Type The type of value for the question.
159 @param[in] Value A pointer to the data being sent to the original
161 @param[out] ActionRequest On return, points to the action requested by the
164 @retval EFI_SUCCESS The callback successfully handled the action.
165 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
166 variable and its data.
167 @retval EFI_DEVICE_ERROR The variable could not be saved.
168 @retval EFI_UNSUPPORTED The specified Action is not supported by the
175 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
176 IN EFI_BROWSER_ACTION Action
,
177 IN EFI_QUESTION_ID QuestionId
,
179 IN EFI_IFR_TYPE_VALUE
*Value
,
180 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
183 VLAN_CONFIG_PRIVATE_DATA
*PrivateData
;
184 VLAN_CONFIGURATION
*Configuration
;
185 EFI_VLAN_CONFIG_PROTOCOL
*VlanConfig
;
187 EFI_HANDLE VlanHandle
;
189 PrivateData
= VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This
);
191 if (Action
== EFI_BROWSER_ACTION_FORM_OPEN
) {
193 // On FORM_OPEN event, update current VLAN list
195 VlanUpdateForm (PrivateData
);
203 Configuration
= AllocateZeroPool (sizeof (VLAN_CONFIGURATION
));
204 ASSERT (Configuration
!= NULL
);
205 HiiGetBrowserData (&mVlanFormSetGuid
, mVlanStorageName
, sizeof (VLAN_CONFIGURATION
), (UINT8
*) Configuration
);
207 VlanConfig
= PrivateData
->VlanConfig
;
209 switch (QuestionId
) {
210 case VLAN_ADD_QUESTION_ID
:
214 VlanConfig
->Set (VlanConfig
, Configuration
->VlanId
, Configuration
->Priority
);
215 VlanUpdateForm (PrivateData
);
218 // Connect the newly created VLAN device
220 VlanHandle
= NetLibGetVlanHandle (PrivateData
->ControllerHandle
, Configuration
->VlanId
);
221 if (VlanHandle
== NULL
) {
223 // There may be no child handle created for VLAN ID 0, connect the parent handle
225 VlanHandle
= PrivateData
->ControllerHandle
;
227 gBS
->ConnectController (VlanHandle
, NULL
, NULL
, TRUE
);
232 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
233 Configuration
->VlanId
= 0;
234 Configuration
->Priority
= 0;
237 case VLAN_REMOVE_QUESTION_ID
:
241 ASSERT (PrivateData
->NumberOfVlan
<= MAX_VLAN_NUMBER
);
242 for (Index
= 0; Index
< PrivateData
->NumberOfVlan
; Index
++) {
243 if (Configuration
->VlanList
[Index
] != 0) {
245 // Checkbox is selected, need remove this VLAN
247 VlanConfig
->Remove (VlanConfig
, PrivateData
->VlanId
[Index
]);
251 VlanUpdateForm (PrivateData
);
252 if (PrivateData
->NumberOfVlan
== 0) {
254 // No VLAN device now, connect the physical NIC handle.
255 // Note: PrivateData->NumberOfVlan has been updated by VlanUpdateForm()
257 gBS
->ConnectController (PrivateData
->ControllerHandle
, NULL
, NULL
, TRUE
);
260 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
261 ZeroMem (Configuration
->VlanList
, MAX_VLAN_NUMBER
);
268 HiiSetBrowserData (&mVlanFormSetGuid
, mVlanStorageName
, sizeof (VLAN_CONFIGURATION
), (UINT8
*) Configuration
, NULL
);
269 FreePool (Configuration
);
275 This function update VLAN list in the VLAN configuration Form.
277 @param[in, out] PrivateData Points to VLAN configuration private data.
282 IN OUT VLAN_CONFIG_PRIVATE_DATA
*PrivateData
285 EFI_VLAN_CONFIG_PROTOCOL
*VlanConfig
;
288 EFI_VLAN_FIND_DATA
*VlanData
;
289 VOID
*StartOpCodeHandle
;
290 EFI_IFR_GUID_LABEL
*StartLabel
;
291 VOID
*EndOpCodeHandle
;
292 EFI_IFR_GUID_LABEL
*EndLabel
;
297 EFI_STRING_ID StringId
;
300 // Find current VLAN configuration
304 VlanConfig
= PrivateData
->VlanConfig
;
305 VlanConfig
->Find (VlanConfig
, NULL
, &NumberOfVlan
, &VlanData
);
308 // Update VLAN configuration in PrivateData
310 if (NumberOfVlan
> MAX_VLAN_NUMBER
) {
311 NumberOfVlan
= MAX_VLAN_NUMBER
;
313 PrivateData
->NumberOfVlan
= NumberOfVlan
;
316 // Init OpCode Handle
318 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
319 ASSERT (StartOpCodeHandle
!= NULL
);
321 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
322 ASSERT (EndOpCodeHandle
!= NULL
);
325 // Create Hii Extend Label OpCode as the start opcode
327 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
331 sizeof (EFI_IFR_GUID_LABEL
)
333 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
334 StartLabel
->Number
= LABEL_VLAN_LIST
;
337 // Create Hii Extend Label OpCode as the end opcode
339 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (
343 sizeof (EFI_IFR_GUID_LABEL
)
345 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
346 EndLabel
->Number
= LABEL_END
;
348 ZeroMem (PrivateData
->VlanId
, MAX_VLAN_NUMBER
);
349 for (Index
= 0; Index
< NumberOfVlan
; Index
++) {
352 StrCpy (String
, L
" VLAN ID:");
355 // Pad VlanId string up to 4 characters with space
357 DigitalCount
= UnicodeValueToString (VlanIdStr
, 0, VlanData
[Index
].VlanId
, 5);
358 SetMem16 (String
, (4 - DigitalCount
) * sizeof (CHAR16
), L
' ');
359 StrCpy (String
+ 4 - DigitalCount
, VlanIdStr
);
362 StrCpy (String
, L
", Priority:");
364 String
+= UnicodeValueToString (String
, 0, VlanData
[Index
].Priority
, 4);
367 StringId
= HiiSetString (PrivateData
->HiiHandle
, 0, VlanStr
, NULL
);
368 ASSERT (StringId
!= 0);
370 HiiCreateCheckBoxOpCode (
372 (EFI_QUESTION_ID
) (VLAN_LIST_VAR_OFFSET
+ Index
),
373 VLAN_CONFIGURATION_VARSTORE_ID
,
374 (UINT16
) (VLAN_LIST_VAR_OFFSET
+ Index
),
376 STRING_TOKEN (STR_VLAN_VLAN_LIST_HELP
),
383 // Save VLAN id to private data
385 PrivateData
->VlanId
[Index
] = VlanData
[Index
].VlanId
;
389 PrivateData
->HiiHandle
, // HII handle
390 &mVlanFormSetGuid
, // Formset GUID
391 VLAN_CONFIGURATION_FORM_ID
, // Form ID
392 StartOpCodeHandle
, // Label for where to insert opcodes
393 EndOpCodeHandle
// Replace data
396 HiiFreeOpCodeHandle (StartOpCodeHandle
);
397 HiiFreeOpCodeHandle (EndOpCodeHandle
);
399 if (VlanData
!= NULL
) {
406 This function publish the VLAN configuration Form for a network device. The
407 HII Config Access protocol will be installed on a child handle of the network
410 @param[in, out] PrivateData Points to VLAN configuration private data.
412 @retval EFI_SUCCESS HII Form is installed for this network device.
413 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
414 @retval Others Other errors as indicated.
418 InstallVlanConfigForm (
419 IN OUT VLAN_CONFIG_PRIVATE_DATA
*PrivateData
423 EFI_HII_HANDLE HiiHandle
;
424 EFI_HANDLE DriverHandle
;
425 CHAR16 Str
[26 + sizeof (EFI_MAC_ADDRESS
) * 2 + 1];
427 EFI_DEVICE_PATH_PROTOCOL
*ChildDevicePath
;
428 EFI_HII_CONFIG_ACCESS_PROTOCOL
*ConfigAccess
;
431 // Create child handle and install HII Config Access Protocol
433 ChildDevicePath
= AppendDevicePathNode (
434 PrivateData
->ParentDevicePath
,
435 (CONST EFI_DEVICE_PATH_PROTOCOL
*) &mHiiVendorDevicePathNode
437 if (ChildDevicePath
== NULL
) {
438 return EFI_OUT_OF_RESOURCES
;
440 PrivateData
->ChildDevicePath
= ChildDevicePath
;
443 ConfigAccess
= &PrivateData
->ConfigAccess
;
444 Status
= gBS
->InstallMultipleProtocolInterfaces (
446 &gEfiDevicePathProtocolGuid
,
448 &gEfiHiiConfigAccessProtocolGuid
,
452 if (EFI_ERROR (Status
)) {
455 PrivateData
->DriverHandle
= DriverHandle
;
458 // Publish the HII package list
460 HiiHandle
= HiiAddPackages (
463 VlanConfigDxeStrings
,
467 if (HiiHandle
== NULL
) {
468 return EFI_OUT_OF_RESOURCES
;
470 PrivateData
->HiiHandle
= HiiHandle
;
473 // Update formset title
476 Status
= NetLibGetMacString (PrivateData
->ControllerHandle
, PrivateData
->ImageHandle
, &MacString
);
477 if (EFI_ERROR (Status
)) {
480 PrivateData
->MacString
= MacString
;
482 StrCpy (Str
, L
"VLAN Configuration (MAC:");
483 StrnCat (Str
, MacString
, sizeof (EFI_MAC_ADDRESS
) * 2);
487 STRING_TOKEN (STR_VLAN_FORM_SET_TITLE
),
497 STRING_TOKEN (STR_VLAN_FORM_TITLE
),
506 This function remove the VLAN configuration Form for a network device. The
507 child handle for HII Config Access protocol will be destroyed.
509 @param[in, out] PrivateData Points to VLAN configuration private data.
513 UninstallVlanConfigForm (
514 IN OUT VLAN_CONFIG_PRIVATE_DATA
*PrivateData
520 if (PrivateData
->MacString
!= NULL
) {
521 FreePool (PrivateData
->MacString
);
522 PrivateData
->MacString
= NULL
;
526 // Uninstall HII package list
528 if (PrivateData
->HiiHandle
!= NULL
) {
529 HiiRemovePackages (PrivateData
->HiiHandle
);
530 PrivateData
->HiiHandle
= NULL
;
534 // Uninstall HII Config Access Protocol
536 if (PrivateData
->DriverHandle
!= NULL
) {
537 gBS
->UninstallMultipleProtocolInterfaces (
538 PrivateData
->DriverHandle
,
539 &gEfiDevicePathProtocolGuid
,
540 PrivateData
->ChildDevicePath
,
541 &gEfiHiiConfigAccessProtocolGuid
,
542 &PrivateData
->ConfigAccess
,
545 PrivateData
->DriverHandle
= NULL
;
547 if (PrivateData
->ChildDevicePath
!= NULL
) {
548 FreePool (PrivateData
->ChildDevicePath
);
549 PrivateData
->ChildDevicePath
= NULL
;