]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/VlanConfigDxe/VlanConfigImpl.c
Clean up the private GUID definition in module Level.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / VlanConfigDxe / VlanConfigImpl.c
1 /** @file
2 HII Config Access protocol implementation of VLAN configuration module.
3
4 Copyright (c) 2009 - 2011, Intel Corporation. All rights reserved.<BR>
5 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
10
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.
13
14 **/
15
16 #include "VlanConfigImpl.h"
17
18 CHAR16 mVlanStorageName[] = L"VlanNvData";
19 EFI_HII_CONFIG_ROUTING_PROTOCOL *mHiiConfigRouting = NULL;
20
21 VLAN_CONFIG_PRIVATE_DATA mVlanConfigPrivateDateTemplate = {
22 VLAN_CONFIG_PRIVATE_DATA_SIGNATURE,
23 {
24 VlanExtractConfig,
25 VlanRouteConfig,
26 VlanCallback
27 }
28 };
29
30 VENDOR_DEVICE_PATH mHiiVendorDevicePathNode = {
31 {
32 HARDWARE_DEVICE_PATH,
33 HW_VENDOR_DP,
34 {
35 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
36 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
37 }
38 },
39 VLAN_CONFIG_FORM_SET_GUID
40 };
41
42 /**
43 This function allows a caller to extract the current configuration for one
44 or more named elements from the target driver.
45
46 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
47 @param[in] Request A null-terminated Unicode string in
48 <ConfigRequest> format.
49 @param[out] Progress On return, points to a character in the Request
50 string. Points to the string's null terminator if
51 request was successful. Points to the most recent
52 '&' before the first failing name/value pair (or
53 the beginning of the string if the failure is in
54 the first name/value pair) if the request was not
55 successful.
56 @param[out] Results A null-terminated Unicode string in
57 <ConfigAltResp> format which has all values filled
58 in for the names in the Request string. String to
59 be allocated by the called function.
60
61 @retval EFI_SUCCESS The Results is filled with the requested values.
62 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
63 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name.
64 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
65 driver.
66
67 **/
68 EFI_STATUS
69 EFIAPI
70 VlanExtractConfig (
71 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
72 IN CONST EFI_STRING Request,
73 OUT EFI_STRING *Progress,
74 OUT EFI_STRING *Results
75 )
76 {
77 EFI_STATUS Status;
78 UINTN BufferSize;
79 VLAN_CONFIGURATION Configuration;
80 VLAN_CONFIG_PRIVATE_DATA *PrivateData;
81 EFI_STRING ConfigRequestHdr;
82 EFI_STRING ConfigRequest;
83 BOOLEAN AllocatedRequest;
84 UINTN Size;
85
86 if (Progress == NULL || Results == NULL) {
87 return EFI_INVALID_PARAMETER;
88 }
89
90 *Progress = Request;
91 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gVlanConfigFormSetGuid, mVlanStorageName)) {
92 return EFI_NOT_FOUND;
93 }
94
95 ConfigRequestHdr = NULL;
96 ConfigRequest = NULL;
97 AllocatedRequest = FALSE;
98 Size = 0;
99
100 //
101 // Retrieve the pointer to the UEFI HII Config Routing Protocol
102 //
103 if (mHiiConfigRouting == NULL) {
104 gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **) &mHiiConfigRouting);
105 }
106 ASSERT (mHiiConfigRouting != NULL);
107
108 //
109 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
110 //
111 PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This);
112 ZeroMem (&Configuration, sizeof (VLAN_CONFIGURATION));
113 BufferSize = sizeof (Configuration);
114 ConfigRequest = Request;
115 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
116 //
117 // Request has no request element, construct full request string.
118 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
119 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
120 //
121 ConfigRequestHdr = HiiConstructConfigHdr (&gVlanConfigFormSetGuid, mVlanStorageName, PrivateData->DriverHandle);
122 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
123 ConfigRequest = AllocateZeroPool (Size);
124 ASSERT (ConfigRequest != NULL);
125 AllocatedRequest = TRUE;
126 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
127 FreePool (ConfigRequestHdr);
128 }
129
130 Status = mHiiConfigRouting->BlockToConfig (
131 mHiiConfigRouting,
132 ConfigRequest,
133 (UINT8 *) &Configuration,
134 BufferSize,
135 Results,
136 Progress
137 );
138 //
139 // Free the allocated config request string.
140 //
141 if (AllocatedRequest) {
142 FreePool (ConfigRequest);
143 ConfigRequest = NULL;
144 }
145 //
146 // Set Progress string to the original request string.
147 //
148 if (Request == NULL) {
149 *Progress = NULL;
150 } else if (StrStr (Request, L"OFFSET") == NULL) {
151 *Progress = Request + StrLen (Request);
152 }
153
154 return Status;
155 }
156
157
158 /**
159 This function processes the results of changes in configuration.
160
161 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
162 @param[in] Configuration A null-terminated Unicode string in <ConfigResp>
163 format.
164 @param[out] Progress A pointer to a string filled in with the offset of
165 the most recent '&' before the first failing
166 name/value pair (or the beginning of the string if
167 the failure is in the first name/value pair) or
168 the terminating NULL if all was successful.
169
170 @retval EFI_SUCCESS The Results is processed successfully.
171 @retval EFI_INVALID_PARAMETER Configuration is NULL.
172 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this
173 driver.
174
175 **/
176 EFI_STATUS
177 EFIAPI
178 VlanRouteConfig (
179 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
180 IN CONST EFI_STRING Configuration,
181 OUT EFI_STRING *Progress
182 )
183 {
184 if (Configuration == NULL || Progress == NULL) {
185 return EFI_INVALID_PARAMETER;
186 }
187
188 *Progress = Configuration;
189 if (!HiiIsConfigHdrMatch (Configuration, &gVlanConfigFormSetGuid, mVlanStorageName)) {
190 return EFI_NOT_FOUND;
191 }
192
193 *Progress = Configuration + StrLen (Configuration);
194 return EFI_SUCCESS;
195 }
196
197 /**
198 This function processes the results of changes in configuration.
199
200 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
201 @param[in] Action Specifies the type of action taken by the browser.
202 @param[in] QuestionId A unique value which is sent to the original
203 exporting driver so that it can identify the type
204 of data to expect.
205 @param[in] Type The type of value for the question.
206 @param[in] Value A pointer to the data being sent to the original
207 exporting driver.
208 @param[out] ActionRequest On return, points to the action requested by the
209 callback function.
210
211 @retval EFI_SUCCESS The callback successfully handled the action.
212 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
213 variable and its data.
214 @retval EFI_DEVICE_ERROR The variable could not be saved.
215 @retval EFI_UNSUPPORTED The specified Action is not supported by the
216 callback.
217
218 **/
219 EFI_STATUS
220 EFIAPI
221 VlanCallback (
222 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
223 IN EFI_BROWSER_ACTION Action,
224 IN EFI_QUESTION_ID QuestionId,
225 IN UINT8 Type,
226 IN EFI_IFR_TYPE_VALUE *Value,
227 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
228 )
229 {
230 VLAN_CONFIG_PRIVATE_DATA *PrivateData;
231 VLAN_CONFIGURATION *Configuration;
232 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
233 UINTN Index;
234 EFI_HANDLE VlanHandle;
235
236 PrivateData = VLAN_CONFIG_PRIVATE_DATA_FROM_THIS (This);
237
238 if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {
239 return EFI_SUCCESS;
240 }
241
242 if (Action == EFI_BROWSER_ACTION_CHANGING) {
243 //
244 // Get Browser data
245 //
246 Configuration = AllocateZeroPool (sizeof (VLAN_CONFIGURATION));
247 ASSERT (Configuration != NULL);
248 HiiGetBrowserData (&gVlanConfigFormSetGuid, mVlanStorageName, sizeof (VLAN_CONFIGURATION), (UINT8 *) Configuration);
249
250 VlanConfig = PrivateData->VlanConfig;
251
252 switch (QuestionId) {
253 case VLAN_ADD_QUESTION_ID:
254 //
255 // Add a VLAN
256 //
257 VlanConfig->Set (VlanConfig, Configuration->VlanId, Configuration->Priority);
258 VlanUpdateForm (PrivateData);
259
260 //
261 // Connect the newly created VLAN device
262 //
263 VlanHandle = NetLibGetVlanHandle (PrivateData->ControllerHandle, Configuration->VlanId);
264 if (VlanHandle == NULL) {
265 //
266 // There may be no child handle created for VLAN ID 0, connect the parent handle
267 //
268 VlanHandle = PrivateData->ControllerHandle;
269 }
270 gBS->ConnectController (VlanHandle, NULL, NULL, TRUE);
271
272 //
273 // Clear UI data
274 //
275 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
276 Configuration->VlanId = 0;
277 Configuration->Priority = 0;
278 break;
279
280 case VLAN_REMOVE_QUESTION_ID:
281 //
282 // Remove VLAN
283 //
284 ASSERT (PrivateData->NumberOfVlan <= MAX_VLAN_NUMBER);
285 for (Index = 0; Index < PrivateData->NumberOfVlan; Index++) {
286 if (Configuration->VlanList[Index] != 0) {
287 //
288 // Checkbox is selected, need remove this VLAN
289 //
290 VlanConfig->Remove (VlanConfig, PrivateData->VlanId[Index]);
291 }
292 }
293
294 VlanUpdateForm (PrivateData);
295 if (PrivateData->NumberOfVlan == 0) {
296 //
297 // No VLAN device now, connect the physical NIC handle.
298 // Note: PrivateData->NumberOfVlan has been updated by VlanUpdateForm()
299 //
300 gBS->ConnectController (PrivateData->ControllerHandle, NULL, NULL, TRUE);
301 }
302
303 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
304 ZeroMem (Configuration->VlanList, MAX_VLAN_NUMBER);
305 break;
306
307 case VLAN_UPDATE_QUESTION_ID:
308 //
309 // Update current VLAN list into Form.
310 //
311 VlanUpdateForm (PrivateData);
312 break;
313
314 default:
315 break;
316 }
317
318 HiiSetBrowserData (&gVlanConfigFormSetGuid, mVlanStorageName, sizeof (VLAN_CONFIGURATION), (UINT8 *) Configuration, NULL);
319 FreePool (Configuration);
320 return EFI_SUCCESS;
321 }
322
323 //
324 // All other action return unsupported.
325 //
326 return EFI_UNSUPPORTED;
327 }
328
329
330 /**
331 This function update VLAN list in the VLAN configuration Form.
332
333 @param[in, out] PrivateData Points to VLAN configuration private data.
334
335 **/
336 VOID
337 VlanUpdateForm (
338 IN OUT VLAN_CONFIG_PRIVATE_DATA *PrivateData
339 )
340 {
341 EFI_VLAN_CONFIG_PROTOCOL *VlanConfig;
342 UINT16 NumberOfVlan;
343 UINTN Index;
344 EFI_VLAN_FIND_DATA *VlanData;
345 VOID *StartOpCodeHandle;
346 EFI_IFR_GUID_LABEL *StartLabel;
347 VOID *EndOpCodeHandle;
348 EFI_IFR_GUID_LABEL *EndLabel;
349 CHAR16 *String;
350 CHAR16 VlanStr[30];
351 CHAR16 VlanIdStr[6];
352 UINTN DigitalCount;
353 EFI_STRING_ID StringId;
354
355 //
356 // Find current VLAN configuration
357 //
358 VlanData = NULL;
359 NumberOfVlan = 0;
360 VlanConfig = PrivateData->VlanConfig;
361 VlanConfig->Find (VlanConfig, NULL, &NumberOfVlan, &VlanData);
362
363 //
364 // Update VLAN configuration in PrivateData
365 //
366 if (NumberOfVlan > MAX_VLAN_NUMBER) {
367 NumberOfVlan = MAX_VLAN_NUMBER;
368 }
369 PrivateData->NumberOfVlan = NumberOfVlan;
370
371 //
372 // Init OpCode Handle
373 //
374 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
375 ASSERT (StartOpCodeHandle != NULL);
376
377 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
378 ASSERT (EndOpCodeHandle != NULL);
379
380 //
381 // Create Hii Extend Label OpCode as the start opcode
382 //
383 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
384 StartOpCodeHandle,
385 &gEfiIfrTianoGuid,
386 NULL,
387 sizeof (EFI_IFR_GUID_LABEL)
388 );
389 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
390 StartLabel->Number = LABEL_VLAN_LIST;
391
392 //
393 // Create Hii Extend Label OpCode as the end opcode
394 //
395 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
396 EndOpCodeHandle,
397 &gEfiIfrTianoGuid,
398 NULL,
399 sizeof (EFI_IFR_GUID_LABEL)
400 );
401 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
402 EndLabel->Number = LABEL_END;
403
404 ZeroMem (PrivateData->VlanId, MAX_VLAN_NUMBER);
405 for (Index = 0; Index < NumberOfVlan; Index++) {
406 String = VlanStr;
407
408 StrCpy (String, L" VLAN ID:");
409 String += 10;
410 //
411 // Pad VlanId string up to 4 characters with space
412 //
413 DigitalCount = UnicodeValueToString (VlanIdStr, 0, VlanData[Index].VlanId, 5);
414 SetMem16 (String, (4 - DigitalCount) * sizeof (CHAR16), L' ');
415 StrCpy (String + 4 - DigitalCount, VlanIdStr);
416 String += 4;
417
418 StrCpy (String, L", Priority:");
419 String += 11;
420 String += UnicodeValueToString (String, 0, VlanData[Index].Priority, 4);
421 *String = 0;
422
423 StringId = HiiSetString (PrivateData->HiiHandle, 0, VlanStr, NULL);
424 ASSERT (StringId != 0);
425
426 HiiCreateCheckBoxOpCode (
427 StartOpCodeHandle,
428 (EFI_QUESTION_ID) (VLAN_LIST_VAR_OFFSET + Index),
429 VLAN_CONFIGURATION_VARSTORE_ID,
430 (UINT16) (VLAN_LIST_VAR_OFFSET + Index),
431 StringId,
432 STRING_TOKEN (STR_VLAN_VLAN_LIST_HELP),
433 0,
434 0,
435 NULL
436 );
437
438 //
439 // Save VLAN id to private data
440 //
441 PrivateData->VlanId[Index] = VlanData[Index].VlanId;
442 }
443
444 HiiUpdateForm (
445 PrivateData->HiiHandle, // HII handle
446 &gVlanConfigFormSetGuid, // Formset GUID
447 VLAN_CONFIGURATION_FORM_ID, // Form ID
448 StartOpCodeHandle, // Label for where to insert opcodes
449 EndOpCodeHandle // Replace data
450 );
451
452 HiiFreeOpCodeHandle (StartOpCodeHandle);
453 HiiFreeOpCodeHandle (EndOpCodeHandle);
454
455 if (VlanData != NULL) {
456 FreePool (VlanData);
457 }
458 }
459
460
461 /**
462 This function publish the VLAN configuration Form for a network device. The
463 HII Config Access protocol will be installed on a child handle of the network
464 device.
465
466 @param[in, out] PrivateData Points to VLAN configuration private data.
467
468 @retval EFI_SUCCESS HII Form is installed for this network device.
469 @retval EFI_OUT_OF_RESOURCES Not enough resource for HII Form installation.
470 @retval Others Other errors as indicated.
471
472 **/
473 EFI_STATUS
474 InstallVlanConfigForm (
475 IN OUT VLAN_CONFIG_PRIVATE_DATA *PrivateData
476 )
477 {
478 EFI_STATUS Status;
479 EFI_HII_HANDLE HiiHandle;
480 EFI_HANDLE DriverHandle;
481 CHAR16 Str[26 + sizeof (EFI_MAC_ADDRESS) * 2 + 1];
482 CHAR16 *MacString;
483 EFI_DEVICE_PATH_PROTOCOL *ChildDevicePath;
484 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
485
486 //
487 // Create child handle and install HII Config Access Protocol
488 //
489 ChildDevicePath = AppendDevicePathNode (
490 PrivateData->ParentDevicePath,
491 (CONST EFI_DEVICE_PATH_PROTOCOL *) &mHiiVendorDevicePathNode
492 );
493 if (ChildDevicePath == NULL) {
494 return EFI_OUT_OF_RESOURCES;
495 }
496 PrivateData->ChildDevicePath = ChildDevicePath;
497
498 DriverHandle = NULL;
499 ConfigAccess = &PrivateData->ConfigAccess;
500 Status = gBS->InstallMultipleProtocolInterfaces (
501 &DriverHandle,
502 &gEfiDevicePathProtocolGuid,
503 ChildDevicePath,
504 &gEfiHiiConfigAccessProtocolGuid,
505 ConfigAccess,
506 NULL
507 );
508 if (EFI_ERROR (Status)) {
509 return Status;
510 }
511 PrivateData->DriverHandle = DriverHandle;
512
513 //
514 // Publish the HII package list
515 //
516 HiiHandle = HiiAddPackages (
517 &gVlanConfigFormSetGuid,
518 DriverHandle,
519 VlanConfigDxeStrings,
520 VlanConfigBin,
521 NULL
522 );
523 if (HiiHandle == NULL) {
524 return EFI_OUT_OF_RESOURCES;
525 }
526 PrivateData->HiiHandle = HiiHandle;
527
528 //
529 // Update formset title help string.
530 //
531 MacString = NULL;
532 Status = NetLibGetMacString (PrivateData->ControllerHandle, PrivateData->ImageHandle, &MacString);
533 if (EFI_ERROR (Status)) {
534 return Status;
535 }
536 PrivateData->MacString = MacString;
537
538 StrCpy (Str, L"VLAN Configuration (MAC:");
539 StrnCat (Str, MacString, sizeof (EFI_MAC_ADDRESS) * 2);
540 StrCat (Str, L")");
541 HiiSetString (
542 HiiHandle,
543 STRING_TOKEN (STR_VLAN_FORM_SET_TITLE_HELP),
544 Str,
545 NULL
546 );
547
548 //
549 // Update form title help string.
550 //
551 HiiSetString (
552 HiiHandle,
553 STRING_TOKEN (STR_VLAN_FORM_HELP),
554 Str,
555 NULL
556 );
557
558 return EFI_SUCCESS;
559 }
560
561 /**
562 This function remove the VLAN configuration Form for a network device. The
563 child handle for HII Config Access protocol will be destroyed.
564
565 @param[in, out] PrivateData Points to VLAN configuration private data.
566
567 **/
568 VOID
569 UninstallVlanConfigForm (
570 IN OUT VLAN_CONFIG_PRIVATE_DATA *PrivateData
571 )
572 {
573 //
574 // Free MAC string
575 //
576 if (PrivateData->MacString != NULL) {
577 FreePool (PrivateData->MacString);
578 PrivateData->MacString = NULL;
579 }
580
581 //
582 // Uninstall HII package list
583 //
584 if (PrivateData->HiiHandle != NULL) {
585 HiiRemovePackages (PrivateData->HiiHandle);
586 PrivateData->HiiHandle = NULL;
587 }
588
589 //
590 // Uninstall HII Config Access Protocol
591 //
592 if (PrivateData->DriverHandle != NULL) {
593 gBS->UninstallMultipleProtocolInterfaces (
594 PrivateData->DriverHandle,
595 &gEfiDevicePathProtocolGuid,
596 PrivateData->ChildDevicePath,
597 &gEfiHiiConfigAccessProtocolGuid,
598 &PrivateData->ConfigAccess,
599 NULL
600 );
601 PrivateData->DriverHandle = NULL;
602
603 if (PrivateData->ChildDevicePath != NULL) {
604 FreePool (PrivateData->ChildDevicePath);
605 PrivateData->ChildDevicePath = NULL;
606 }
607 }
608 }