]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigNv.c
Remove SMM_CORE from SmmServicesTableLib.inf that is dedicated for DXE_SMM_DRIVER
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4ConfigDxe / Ip4ConfigNv.c
CommitLineData
63886849 1/** @file\r
2 Helper functions for configuring or getting the parameters relating to Ip4.\r
3\r
c22b6cdf 4Copyright (c) 2009 - 2010, Intel Corporation.<BR>\r
63886849 5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "Ip4ConfigNv.h"\r
16\r
d80ea739 17EFI_GUID mNicIp4ConfigNvDataGuid = EFI_NIC_IP4_CONFIG_NVDATA_GUID;\r
63886849 18\r
63886849 19\r
20/**\r
21 Calculate the prefix length of the IPv4 subnet mask.\r
22\r
23 @param[in] SubnetMask The IPv4 subnet mask.\r
24\r
25 @return The prefix length of the subnet mask.\r
26 @retval 0 Other errors as indicated.\r
27**/\r
28UINT8\r
29GetSubnetMaskPrefixLength (\r
30 IN EFI_IPv4_ADDRESS *SubnetMask\r
31 )\r
32{\r
33 UINT8 Len;\r
34 UINT32 ReverseMask;\r
35\r
36 //\r
37 // The SubnetMask is in network byte order.\r
38 //\r
39 ReverseMask = (SubnetMask->Addr[0] << 24) | (SubnetMask->Addr[1] << 16) | (SubnetMask->Addr[2] << 8) | (SubnetMask->Addr[3]);\r
40\r
41 //\r
42 // Reverse it.\r
43 //\r
44 ReverseMask = ~ReverseMask;\r
45\r
46 if ((ReverseMask & (ReverseMask + 1)) != 0) {\r
47 return 0;\r
48 }\r
49\r
50 Len = 0;\r
51\r
52 while (ReverseMask != 0) {\r
53 ReverseMask = ReverseMask >> 1;\r
54 Len++;\r
55 }\r
56\r
57 return (UINT8) (32 - Len);\r
58}\r
59\r
60/**\r
61 Convert the decimal dotted IPv4 address into the binary IPv4 address.\r
62\r
63 @param[in] Str The UNICODE string.\r
64 @param[out] Ip The storage to return the ASCII string.\r
65\r
66 @retval EFI_SUCCESS The binary IP address is returned in Ip.\r
67 @retval EFI_INVALID_PARAMETER The IP string is malformatted.\r
68**/\r
69EFI_STATUS\r
70Ip4AsciiStrToIp (\r
71 IN CHAR8 *Str,\r
72 OUT EFI_IPv4_ADDRESS *Ip\r
73 )\r
74{\r
75 UINTN Index;\r
76 UINTN Number;\r
77\r
78 Index = 0;\r
79\r
80 while (*Str != 0) {\r
81\r
82 if (Index > 3) {\r
83 return EFI_INVALID_PARAMETER;\r
84 }\r
85\r
86 Number = 0;\r
87 while (NET_IS_DIGIT (*Str)) {\r
88 Number = Number * 10 + (*Str - '0');\r
89 Str++;\r
90 }\r
91\r
92 if (Number > 0xFF) {\r
93 return EFI_INVALID_PARAMETER;\r
94 }\r
95\r
96 Ip->Addr[Index] = (UINT8) Number;\r
97\r
98 if ((*Str != '\0') && (*Str != '.')) {\r
99 //\r
100 // The current character should be either the NULL terminator or\r
101 // the dot delimiter.\r
102 //\r
103 return EFI_INVALID_PARAMETER;\r
104 }\r
105\r
106 if (*Str == '.') {\r
107 //\r
108 // Skip the delimiter.\r
109 //\r
110 Str++;\r
111 }\r
112\r
113 Index++;\r
114 }\r
115\r
116 if (Index != 4) {\r
117 return EFI_INVALID_PARAMETER;\r
118 }\r
119\r
120 return EFI_SUCCESS;\r
121}\r
122\r
123/**\r
124 Convert the IPv4 address into a dotted string.\r
125\r
126 @param[in] Ip The IPv4 address.\r
127 @param[out] Str The dotted IP string.\r
128**/\r
129VOID\r
130Ip4ConfigIpToStr (\r
131 IN EFI_IPv4_ADDRESS *Ip,\r
132 OUT CHAR16 *Str\r
133 )\r
134{\r
135 UnicodeSPrint (Str, 2 * IP4_STR_MAX_SIZE, L"%d.%d.%d.%d", Ip->Addr[0], Ip->Addr[1], Ip->Addr[2], Ip->Addr[3]);\r
136}\r
137\r
138\r
139/**\r
140 Convert the network configuration data into the IFR data.\r
141\r
f6b7393c 142 @param[in] Ip4ConfigInstance The IP4Config instance\r
143 @param[out] IfrFormNvData The IFR nv data.\r
63886849 144**/\r
145VOID\r
146Ip4ConfigConvertDeviceConfigDataToIfrNvData (\r
147 IN IP4_CONFIG_INSTANCE *Ip4ConfigInstance,\r
148 OUT IP4_CONFIG_IFR_NVDATA *IfrFormNvData\r
149 )\r
150{\r
151 EFI_STATUS Status;\r
152 NIC_IP4_CONFIG_INFO *NicConfig;\r
153 UINTN ConfigLen;\r
154\r
63886849 155 ConfigLen = sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * 2;\r
156 NicConfig = AllocateZeroPool (ConfigLen);\r
157 ASSERT (NicConfig != NULL);\r
158 Status = EfiNicIp4ConfigGetInfo (Ip4ConfigInstance, &ConfigLen, NicConfig);\r
159 if (!EFI_ERROR (Status)) {\r
c22b6cdf 160 IfrFormNvData->Configure = 1;\r
63886849 161 if (NicConfig->Source == IP4_CONFIG_SOURCE_DHCP) {\r
162 IfrFormNvData->DhcpEnable = 1;\r
163 } else {\r
164 IfrFormNvData->DhcpEnable = 0;\r
165 Ip4ConfigIpToStr (&NicConfig->Ip4Info.StationAddress, IfrFormNvData->StationAddress);\r
166 Ip4ConfigIpToStr (&NicConfig->Ip4Info.SubnetMask, IfrFormNvData->SubnetMask);\r
167 Ip4ConfigIpToStr (&NicConfig->Ip4Info.RouteTable[1].GatewayAddress, IfrFormNvData->GatewayAddress);\r
168 }\r
c22b6cdf 169 } else {\r
170 IfrFormNvData->Configure = 0;\r
63886849 171 }\r
c22b6cdf 172\r
63886849 173 FreePool (NicConfig);\r
174}\r
175\r
176/**\r
d80ea739 177 Convert the IFR data into the network configuration data and set the IP\r
178 configure parameters for the NIC.\r
179\r
d80ea739 180 @param[in, out] Ip4ConfigInstance The IP4Config instance.\r
c22b6cdf 181\r
182 @retval EFI_SUCCESS The configure parameter for this NIC was\r
d80ea739 183 set successfully.\r
184 @retval EFI_ALREADY_STARTED There is a pending auto configuration.\r
185 @retval EFI_NOT_FOUND No auto configure parameter is found.\r
c22b6cdf 186\r
63886849 187**/\r
d80ea739 188EFI_STATUS\r
189Ip4ConfigConvertIfrNvDataToDeviceConfigData (\r
d80ea739 190 IN OUT IP4_CONFIG_INSTANCE *Ip4ConfigInstance\r
63886849 191 )\r
192{\r
c22b6cdf 193 EFI_STATUS Status;\r
d80ea739 194 EFI_IP_ADDRESS HostIp;\r
195 EFI_IP_ADDRESS SubnetMask;\r
196 EFI_IP_ADDRESS Gateway;\r
197 EFI_INPUT_KEY Key;\r
198 NIC_IP4_CONFIG_INFO *NicInfo;\r
199 EFI_IP_ADDRESS Ip;\r
63886849 200\r
c22b6cdf 201 if (!Ip4ConfigInstance->Ip4ConfigCallbackInfo.Configured) {\r
202 //\r
203 // Clear the variable\r
204 //\r
205 ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo, sizeof (IP4_SETTING_INFO));\r
206\r
207 Status = EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NULL, TRUE);\r
208 if (Status == EFI_NOT_FOUND) {\r
209 return EFI_SUCCESS;\r
210 }\r
211\r
212 return Status;\r
213 }\r
214\r
d80ea739 215 NicInfo = AllocateZeroPool (sizeof (NIC_IP4_CONFIG_INFO) + 2 * sizeof (EFI_IP4_ROUTE_TABLE));\r
216 ASSERT (NicInfo != NULL);\r
63886849 217\r
d80ea739 218 NicInfo->Ip4Info.RouteTable = (EFI_IP4_ROUTE_TABLE *) (NicInfo + 1);\r
219\r
c22b6cdf 220 if (!Ip4ConfigInstance->Ip4ConfigCallbackInfo.DhcpEnabled) {\r
d80ea739 221 CopyMem (&HostIp.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, sizeof (HostIp.v4));\r
222 CopyMem (&SubnetMask.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, sizeof (SubnetMask.v4));\r
223 CopyMem (&Gateway.v4, &Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, sizeof (Gateway.v4));\r
224\r
c22b6cdf 225 if (!NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {\r
226 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);\r
227 return EFI_INVALID_PARAMETER;\r
228 }\r
229 if (EFI_IP4_EQUAL (&SubnetMask, &mZeroIp4Addr)) {\r
230 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL);\r
231 return EFI_INVALID_PARAMETER;\r
232 }\r
233\r
d80ea739 234 if ((Gateway.Addr[0] != 0)) {\r
235 if (SubnetMask.Addr[0] == 0) {\r
236 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Gateway address is set but subnet mask is zero.", NULL);\r
237 return EFI_INVALID_PARAMETER;\r
238\r
239 } else if (!IP4_NET_EQUAL (HostIp.Addr[0], Gateway.Addr[0], SubnetMask.Addr[0])) {\r
240 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Local IP and Gateway are not in the same subnet.", NULL);\r
241 return EFI_INVALID_PARAMETER; }\r
63886849 242 }\r
243\r
d80ea739 244 NicInfo->Source = IP4_CONFIG_SOURCE_STATIC;\r
245 NicInfo->Ip4Info.RouteTableSize = 2;\r
246\r
247 CopyMem (&NicInfo->Ip4Info.StationAddress, &HostIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
248 CopyMem (&NicInfo->Ip4Info.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
249\r
250 Ip.Addr[0] = HostIp.Addr[0] & SubnetMask.Addr[0];\r
251\r
252 CopyMem (&NicInfo->Ip4Info.RouteTable[0].SubnetAddress, &Ip.v4, sizeof (EFI_IPv4_ADDRESS));\r
253 CopyMem (&NicInfo->Ip4Info.RouteTable[0].SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
254 CopyMem (&NicInfo->Ip4Info.RouteTable[1].GatewayAddress, &Gateway.v4, sizeof (EFI_IPv4_ADDRESS));\r
c22b6cdf 255\r
d80ea739 256 } else {\r
257 NicInfo->Source = IP4_CONFIG_SOURCE_DHCP;\r
c22b6cdf 258 ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, sizeof (EFI_IPv4_ADDRESS));\r
259 ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
260 ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, sizeof (EFI_IPv4_ADDRESS));\r
63886849 261 }\r
262\r
d80ea739 263 NicInfo->Perment = TRUE;\r
264 CopyMem (&NicInfo->NicAddr, &Ip4ConfigInstance->NicAddr, sizeof (NIC_ADDR));\r
265\r
266 return EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NicInfo, TRUE);\r
63886849 267}\r
268\r
269/**\r
270 This function allows the caller to request the current\r
271 configuration for one or more named elements. The resulting\r
272 string is in <ConfigAltResp> format. Any and all alternative\r
273 configuration strings shall also be appended to the end of the\r
274 current configuration string. If they are, they must appear\r
275 after the current configuration. They must contain the same\r
276 routing (GUID, NAME, PATH) as the current configuration string.\r
277 They must have an additional description indicating the type of\r
278 alternative configuration the string represents,\r
279 "ALTCFG=<StringToken>". That <StringToken> (when\r
280 converted from Hex UNICODE to binary) is a reference to a\r
281 string in the associated string pack.\r
282\r
283 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
284 @param[in] Request A null-terminated Unicode string in\r
285 <ConfigRequest> format. Note that this\r
286 includes the routing information as well as\r
287 the configurable name / value pairs. It is\r
288 invalid for this string to be in\r
289 <MultiConfigRequest> format.\r
290 @param[out] Progress On return, points to a character in the\r
291 Request string. Points to the string's null\r
292 terminator if request was successful. Points\r
293 to the most recent "&" before the first\r
294 failing name / value pair (or the beginning\r
295 of the string if the failure is in the first\r
296 name / value pair) if the request was not\r
297 successful.\r
298 @param[out] Results A null-terminated Unicode string in\r
299 <ConfigAltResp> format which has all values\r
300 filled in for the names in the Request string.\r
301 String to be allocated by the called function.\r
302\r
303 @retval EFI_SUCCESS The Results string is filled with the\r
304 values corresponding to all requested\r
305 names.\r
306 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
307 parts of the results that must be\r
308 stored awaiting possible future\r
309 protocols.\r
310 @retval EFI_INVALID_PARAMETER For example, passing in a NULL\r
311 for the Request parameter\r
312 would result in this type of\r
313 error. In this case, the\r
314 Progress parameter would be\r
315 set to NULL.\r
316 @retval EFI_NOT_FOUND Routing data doesn't match any\r
317 known driver. Progress set to the\r
318 first character in the routing header.\r
319 Note: There is no requirement that the\r
320 driver validate the routing data. It\r
321 must skip the <ConfigHdr> in order to\r
322 process the names.\r
323 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set\r
324 to most recent & before the\r
325 error or the beginning of the\r
326 string.\r
327 @retval EFI_INVALID_PARAMETER Unknown name. Progress points\r
328 to the & before the name in\r
329 question.Currently not implemented.\r
330**/\r
331EFI_STATUS\r
332EFIAPI\r
333Ip4DeviceExtractConfig (\r
334 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
335 IN CONST EFI_STRING Request,\r
336 OUT EFI_STRING *Progress,\r
337 OUT EFI_STRING *Results\r
338 )\r
339{\r
340 EFI_STATUS Status;\r
341 UINTN ConfigLen;\r
342 NIC_IP4_CONFIG_INFO *IfrDeviceNvData;\r
63886849 343 IP4_CONFIG_INSTANCE *Ip4ConfigInstance;\r
d80ea739 344 IP4_CONFIG_IFR_NVDATA *IfrFormNvData;\r
59aefb7e
LG
345 EFI_STRING ConfigRequestHdr;\r
346 EFI_STRING ConfigRequest;\r
347 EFI_STRING DeviceResult;\r
348 EFI_STRING FormResult;\r
349 CHAR16 *StrPointer;\r
350 BOOLEAN AllocatedRequest;\r
351 UINTN Size;\r
352 UINTN BufferSize;\r
353\r
354 if (Progress == NULL || Results == NULL) {\r
63886849 355 return EFI_INVALID_PARAMETER;\r
356 }\r
357\r
59aefb7e
LG
358 *Progress = Request;\r
359 Size = 0;\r
360 DeviceResult = NULL;\r
361 FormResult = NULL;\r
362 ConfigRequest = NULL;\r
363 Status = EFI_SUCCESS;\r
364 AllocatedRequest = FALSE;\r
d80ea739 365 Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This);\r
366\r
391a0724 367 //\r
368 // Check Request data in <ConfigHdr>.\r
369 //\r
59aefb7e 370 if ((Request == NULL) || HiiIsConfigHdrMatch (Request, &gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
d80ea739 371 IfrDeviceNvData = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);\r
372 if (IfrDeviceNvData == NULL) {\r
373 return EFI_OUT_OF_RESOURCES;\r
374 }\r
391a0724 375\r
d80ea739 376 ConfigLen = sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * 2;\r
377 Status = EfiNicIp4ConfigGetInfo (Ip4ConfigInstance, &ConfigLen, IfrDeviceNvData);\r
378 if (EFI_ERROR (Status)) {\r
379 FreePool (IfrDeviceNvData);\r
380 return EFI_NOT_FOUND;\r
381 }\r
c22b6cdf 382\r
59aefb7e
LG
383 ConfigRequest = Request;\r
384 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
385 //\r
386 // Request has no request element, construct full request string.\r
387 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
388 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
389 //\r
390 ConfigRequestHdr = HiiConstructConfigHdr (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, Ip4ConfigInstance->ChildHandle);\r
391 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
392 ConfigRequest = AllocateZeroPool (Size);\r
393 ASSERT (ConfigRequest != NULL);\r
394 AllocatedRequest = TRUE;\r
395 BufferSize = NIC_ITEM_CONFIG_SIZE;\r
396 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
397 FreePool (ConfigRequestHdr);\r
398 }\r
399\r
d80ea739 400 //\r
401 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
402 //\r
403 Status = gHiiConfigRouting->BlockToConfig (\r
404 gHiiConfigRouting,\r
59aefb7e 405 ConfigRequest,\r
d80ea739 406 (UINT8 *) IfrDeviceNvData,\r
407 NIC_ITEM_CONFIG_SIZE,\r
59aefb7e 408 &DeviceResult,\r
d80ea739 409 Progress\r
410 );\r
c22b6cdf 411\r
d80ea739 412 FreePool (IfrDeviceNvData);\r
59aefb7e
LG
413 //\r
414 // Free the allocated config request string.\r
415 //\r
416 if (AllocatedRequest) {\r
417 FreePool (ConfigRequest);\r
418 ConfigRequest = NULL;\r
419 }\r
63886849 420\r
59aefb7e
LG
421 if (EFI_ERROR (Status)) {\r
422 goto Failure;\r
423 }\r
424 } \r
425 \r
426 if ((Request == NULL) || HiiIsConfigHdrMatch (Request, &mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
63886849 427\r
d80ea739 428 IfrFormNvData = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);\r
429 if (IfrFormNvData == NULL) {\r
430 return EFI_OUT_OF_RESOURCES;\r
431 }\r
c22b6cdf 432\r
d80ea739 433 Ip4ConfigConvertDeviceConfigDataToIfrNvData (Ip4ConfigInstance, IfrFormNvData);\r
c22b6cdf 434\r
59aefb7e
LG
435 ConfigRequest = Request;\r
436 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
437 //\r
438 // Request has no request element, construct full request string.\r
439 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
440 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
441 //\r
442 ConfigRequestHdr = HiiConstructConfigHdr (&mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE, Ip4ConfigInstance->ChildHandle);\r
443 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
444 ConfigRequest = AllocateZeroPool (Size);\r
445 ASSERT (ConfigRequest != NULL);\r
446 AllocatedRequest = TRUE;\r
447 BufferSize = sizeof (IP4_CONFIG_IFR_NVDATA);\r
448 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
449 FreePool (ConfigRequestHdr);\r
450 }\r
451 \r
d80ea739 452 //\r
453 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
454 //\r
455 Status = gHiiConfigRouting->BlockToConfig (\r
456 gHiiConfigRouting,\r
59aefb7e 457 ConfigRequest,\r
d80ea739 458 (UINT8 *) IfrFormNvData,\r
459 sizeof (IP4_CONFIG_IFR_NVDATA),\r
59aefb7e 460 &FormResult,\r
d80ea739 461 Progress\r
462 );\r
c22b6cdf 463\r
d80ea739 464 FreePool (IfrFormNvData);\r
59aefb7e
LG
465 //\r
466 // Free the allocated config request string.\r
467 //\r
468 if (AllocatedRequest) {\r
469 FreePool (ConfigRequest);\r
470 ConfigRequest = NULL;\r
471 }\r
472\r
473 if (EFI_ERROR (Status)) {\r
474 goto Failure;\r
475 }\r
476 }\r
d80ea739 477\r
59aefb7e
LG
478 if (Request == NULL) {\r
479 Size = StrLen (DeviceResult);\r
480 Size = Size + 1;\r
481 Size = Size + StrLen (FormResult) + 1;\r
482 *Results = AllocateZeroPool (Size * sizeof (CHAR16));\r
483 ASSERT (*Results != NULL);\r
484 StrPointer = *Results;\r
485 StrCpy (StrPointer, DeviceResult);\r
486 StrPointer = StrPointer + StrLen (StrPointer);\r
487 *StrPointer = L'&';\r
488 StrCpy (StrPointer + 1, FormResult);\r
489 FreePool (DeviceResult);\r
490 FreePool (FormResult);\r
491 } else if (HiiIsConfigHdrMatch (ConfigRequest, &gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
492 *Results = DeviceResult;\r
493 } else if (HiiIsConfigHdrMatch (ConfigRequest, &mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
494 *Results = FormResult;\r
d80ea739 495 } else {\r
63886849 496 return EFI_NOT_FOUND;\r
497 }\r
498\r
59aefb7e
LG
499Failure:\r
500 //\r
501 // Set Progress string to the original request string.\r
502 //\r
503 if (Request == NULL) {\r
504 *Progress = NULL;\r
505 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
506 *Progress = Request + StrLen (Request);\r
507 }\r
508 \r
63886849 509 return Status;\r
510}\r
511\r
512/**\r
513 This function applies changes in a driver's configuration.\r
514 Input is a Configuration, which has the routing data for this\r
515 driver followed by name / value configuration pairs. The driver\r
516 must apply those pairs to its configurable storage. If the\r
517 driver's configuration is stored in a linear block of data\r
518 and the driver's name / value pairs are in <BlockConfig>\r
519 format, it may use the ConfigToBlock helper function (above) to\r
520 simplify the job. Currently not implemented.\r
521\r
522 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
523 @param[in] Configuration A null-terminated Unicode string in\r
524 <ConfigString> format.\r
525 @param[out] Progress A pointer to a string filled in with the\r
526 offset of the most recent '&' before the\r
527 first failing name / value pair (or the\r
528 beginn ing of the string if the failure\r
529 is in the first name / value pair) or\r
530 the terminating NULL if all was\r
531 successful.\r
532\r
533 @retval EFI_SUCCESS The results have been distributed or are\r
534 awaiting distribution.\r
535 @retval EFI_OUT_OF_MEMORY Not enough memory to store the\r
536 parts of the results that must be\r
537 stored awaiting possible future\r
538 protocols.\r
539 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
540 Results parameter would result\r
541 in this type of error.\r
542 @retval EFI_NOT_FOUND Target for the specified routing data\r
543 was not found.\r
544**/\r
545EFI_STATUS\r
546EFIAPI\r
547Ip4DeviceRouteConfig (\r
548 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
549 IN CONST EFI_STRING Configuration,\r
550 OUT EFI_STRING *Progress\r
551 )\r
552{\r
553 EFI_STATUS Status;\r
554 UINTN BufferSize;\r
555 NIC_IP4_CONFIG_INFO *IfrDeviceNvData;\r
c22b6cdf 556 IP4_CONFIG_IFR_NVDATA *IfrFormNvData;\r
391a0724 557 NIC_IP4_CONFIG_INFO *NicInfo;\r
63886849 558 IP4_CONFIG_INSTANCE *Ip4ConfigInstance;\r
559 EFI_MAC_ADDRESS ZeroMac;\r
560\r
d80ea739 561 if (Configuration == NULL || Progress == NULL) {\r
63886849 562 return EFI_INVALID_PARAMETER;\r
563 }\r
564\r
565 *Progress = Configuration;\r
566\r
d80ea739 567 Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This);\r
63886849 568\r
569 //\r
d80ea739 570 // Check Routing data in <ConfigHdr>.\r
63886849 571 //\r
d80ea739 572 if (HiiIsConfigHdrMatch (Configuration, &mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
573 //\r
574 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
575 //\r
576 IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA));\r
577 if (IfrFormNvData == NULL) {\r
578 return EFI_OUT_OF_RESOURCES;\r
63886849 579 }\r
63886849 580\r
d80ea739 581 BufferSize = NIC_ITEM_CONFIG_SIZE;\r
582 Status = gHiiConfigRouting->ConfigToBlock (\r
583 gHiiConfigRouting,\r
584 Configuration,\r
585 (UINT8 *) IfrFormNvData,\r
586 &BufferSize,\r
587 Progress\r
588 );\r
589 if (!EFI_ERROR (Status)) {\r
c22b6cdf 590 Status = Ip4ConfigConvertIfrNvDataToDeviceConfigData (Ip4ConfigInstance);\r
d80ea739 591 }\r
c22b6cdf 592\r
d80ea739 593 FreePool (IfrFormNvData);\r
63886849 594\r
d80ea739 595 } else if (HiiIsConfigHdrMatch (Configuration, &gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
63886849 596\r
d80ea739 597 IfrDeviceNvData = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);\r
598 if (IfrDeviceNvData == NULL) {\r
599 return EFI_OUT_OF_RESOURCES;\r
600 }\r
63886849 601\r
d80ea739 602 BufferSize = NIC_ITEM_CONFIG_SIZE;\r
603 Status = gHiiConfigRouting->ConfigToBlock (\r
604 gHiiConfigRouting,\r
605 Configuration,\r
606 (UINT8 *) IfrDeviceNvData,\r
607 &BufferSize,\r
608 Progress\r
609 );\r
610 if (!EFI_ERROR (Status)) {\r
611 ZeroMem (&ZeroMac, sizeof (EFI_MAC_ADDRESS));\r
612 if (CompareMem (&IfrDeviceNvData->NicAddr.MacAddr, &ZeroMac, IfrDeviceNvData->NicAddr.Len) != 0) {\r
613 BufferSize = sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * IfrDeviceNvData->Ip4Info.RouteTableSize;\r
c22b6cdf 614 NicInfo = AllocateCopyPool (BufferSize, IfrDeviceNvData);\r
d80ea739 615 Status = EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NicInfo, TRUE);\r
616 } else {\r
c22b6cdf 617 ZeroMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo, sizeof (IP4_SETTING_INFO));\r
d80ea739 618 Status = EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NULL, TRUE);\r
619 }\r
620 }\r
63886849 621\r
d80ea739 622 FreePool (IfrDeviceNvData);\r
63886849 623\r
d80ea739 624 } else {\r
ae79d2f9 625\r
ae79d2f9
LG
626 return EFI_NOT_FOUND;\r
627 }\r
c22b6cdf 628\r
d80ea739 629 return Status;\r
ae79d2f9 630\r
63886849 631}\r
632\r
633/**\r
634 This function is called to provide results data to the driver.\r
635 This data consists of a unique key that is used to identify\r
636 which data is either being passed back or being asked for.\r
637\r
638 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
639 @param[in] Action Specifies the type of action taken by the browser.\r
640 @param[in] QuestionId A unique value which is sent to the original\r
641 exporting driver so that it can identify the type\r
642 of data to expect. The format of the data tends to\r
643 vary based on the opcode that enerated the callback.\r
644 @param[in] Type The type of value for the question.\r
645 @param[in] Value A pointer to the data being sent to the original\r
646 exporting driver.\r
647 @param[out] ActionRequest On return, points to the action requested by the\r
648 callback function.\r
649\r
650 @retval EFI_SUCCESS The callback successfully handled the action.\r
651 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
652 variable and its data.\r
653 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
654 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
655 callback.Currently not implemented.\r
656 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.\r
657 @retval Others Other errors as indicated.\r
658**/\r
659EFI_STATUS\r
660EFIAPI\r
661Ip4FormCallback (\r
662 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
663 IN EFI_BROWSER_ACTION Action,\r
664 IN EFI_QUESTION_ID QuestionId,\r
665 IN UINT8 Type,\r
666 IN EFI_IFR_TYPE_VALUE *Value,\r
667 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
668 )\r
669{\r
670 IP4_CONFIG_INSTANCE *Ip4ConfigInstance;\r
63886849 671 CHAR8 Ip4String[IP4_STR_MAX_SIZE];\r
63886849 672 IP4_CONFIG_IFR_NVDATA *IfrFormNvData;\r
63886849 673 EFI_IP_ADDRESS HostIp;\r
674 EFI_IP_ADDRESS SubnetMask;\r
675 EFI_IP_ADDRESS Gateway;\r
676 EFI_STATUS Status;\r
677 EFI_INPUT_KEY Key;\r
63886849 678\r
d80ea739 679 Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_CONFIG_ACCESS (This);\r
63886849 680\r
681 IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA));\r
682 if (IfrFormNvData == NULL) {\r
683 return EFI_OUT_OF_RESOURCES;\r
684 }\r
685\r
686 //\r
687 // Retrive uncommitted data from Browser\r
688 //\r
d80ea739 689 if (!HiiGetBrowserData (&mNicIp4ConfigNvDataGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData)) {\r
63886849 690 FreePool (IfrFormNvData);\r
691 return EFI_NOT_FOUND;\r
692 }\r
693\r
694 Status = EFI_SUCCESS;\r
695\r
696 switch (QuestionId) {\r
697\r
c22b6cdf 698 case KEY_ENABLE:\r
699 if (IfrFormNvData->Configure == 0) {\r
700 Ip4ConfigInstance->Ip4ConfigCallbackInfo.Configured = FALSE;\r
701 } else {\r
702 Ip4ConfigInstance->Ip4ConfigCallbackInfo.Configured = TRUE;\r
703 }\r
704 break;\r
705\r
63886849 706 case KEY_DHCP_ENABLE:\r
707 if (IfrFormNvData->DhcpEnable == 0) {\r
c22b6cdf 708 Ip4ConfigInstance->Ip4ConfigCallbackInfo.DhcpEnabled = FALSE;\r
63886849 709 } else {\r
c22b6cdf 710 Ip4ConfigInstance->Ip4ConfigCallbackInfo.DhcpEnabled = TRUE;\r
63886849 711 }\r
712\r
713 break;\r
714\r
715 case KEY_LOCAL_IP:\r
716 UnicodeStrToAsciiStr (IfrFormNvData->StationAddress, Ip4String);\r
717 Status = Ip4AsciiStrToIp (Ip4String, &HostIp.v4);\r
f6b7393c 718 if (EFI_ERROR (Status) || !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {\r
63886849 719 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);\r
720 Status = EFI_INVALID_PARAMETER;\r
721 } else {\r
d80ea739 722 CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.LocalIp, &HostIp.v4, sizeof (HostIp.v4));\r
63886849 723 }\r
724\r
725 break;\r
726\r
727 case KEY_SUBNET_MASK:\r
728 UnicodeStrToAsciiStr (IfrFormNvData->SubnetMask, Ip4String);\r
729 Status = Ip4AsciiStrToIp (Ip4String, &SubnetMask.v4);\r
730 if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {\r
731 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid SubnetMask!", NULL);\r
732 Status = EFI_INVALID_PARAMETER;\r
733 } else {\r
d80ea739 734 CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));\r
63886849 735 }\r
736\r
737 break;\r
738\r
739 case KEY_GATE_WAY:\r
740 UnicodeStrToAsciiStr (IfrFormNvData->GatewayAddress, Ip4String);\r
741 Status = Ip4AsciiStrToIp (Ip4String, &Gateway.v4);\r
f6b7393c 742 if (EFI_ERROR (Status) || ((Gateway.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), 0))) {\r
63886849 743 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);\r
744 Status = EFI_INVALID_PARAMETER;\r
745 } else {\r
d80ea739 746 CopyMem (&Ip4ConfigInstance->Ip4ConfigCallbackInfo.Gateway, &Gateway.v4, sizeof (Gateway.v4));\r
63886849 747 }\r
748\r
749 break;\r
750\r
751 case KEY_SAVE_CHANGES:\r
c22b6cdf 752\r
753 Status = Ip4ConfigConvertIfrNvDataToDeviceConfigData (Ip4ConfigInstance);\r
754\r
63886849 755 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
d80ea739 756\r
63886849 757 break;\r
758\r
759 default:\r
c22b6cdf 760\r
63886849 761 break;\r
762 }\r
763\r
764 if (!EFI_ERROR (Status)) {\r
63886849 765 //\r
766 // Pass changed uncommitted data back to Form Browser\r
767 //\r
768 HiiSetBrowserData (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData, NULL);\r
769 }\r
770\r
771 FreePool (IfrFormNvData);\r
d80ea739 772\r
63886849 773 return Status;\r
774}\r
775\r
776/**\r
777 Install HII Config Access protocol for network device and allocate resource.\r
778\r
779 @param[in] Instance The IP4 Config instance.\r
780\r
781 @retval EFI_SUCCESS The HII Config Access protocol is installed.\r
782 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
783 @retval Others Other errors as indicated.\r
784**/\r
785EFI_STATUS\r
786Ip4ConfigDeviceInit (\r
d80ea739 787 IN IP4_CONFIG_INSTANCE *Instance\r
63886849 788 )\r
789{\r
d80ea739 790 EFI_STATUS Status;\r
791 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
792 VENDOR_DEVICE_PATH VendorDeviceNode;\r
793 EFI_SERVICE_BINDING_PROTOCOL *MnpSb;\r
794 CHAR16 *MacString;\r
795 CHAR16 MenuString[128];\r
796 CHAR16 PortString[128];\r
797 CHAR16 *OldMenuString;\r
63886849 798\r
d80ea739 799 ConfigAccess = &Instance->HiiConfigAccessProtocol;\r
800 ConfigAccess->ExtractConfig = Ip4DeviceExtractConfig;\r
801 ConfigAccess->RouteConfig = Ip4DeviceRouteConfig;\r
802 ConfigAccess->Callback = Ip4FormCallback;\r
63886849 803\r
d80ea739 804 //\r
805 // Construct device path node for EFI HII Config Access protocol,\r
806 // which consists of controller physical device path and one hardware\r
807 // vendor guid node.\r
808 //\r
809 ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));\r
810 VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;\r
811 VendorDeviceNode.Header.SubType = HW_VENDOR_DP;\r
63886849 812\r
d80ea739 813 CopyGuid (&VendorDeviceNode.Guid, &gEfiNicIp4ConfigVariableGuid);\r
63886849 814\r
d80ea739 815 SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));\r
816 Instance->HiiVendorDevicePath = AppendDevicePathNode (\r
817 Instance->ParentDevicePath,\r
818 (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode\r
819 );\r
63886849 820\r
d80ea739 821 Instance->ChildHandle = NULL;\r
63886849 822 //\r
d80ea739 823 // Install Device Path Protocol and Config Access protocol on new handle\r
63886849 824 //\r
825 Status = gBS->InstallMultipleProtocolInterfaces (\r
d80ea739 826 &Instance->ChildHandle,\r
827 &gEfiDevicePathProtocolGuid,\r
c22b6cdf 828 Instance->HiiVendorDevicePath,\r
63886849 829 &gEfiHiiConfigAccessProtocolGuid,\r
d80ea739 830 ConfigAccess,\r
63886849 831 NULL\r
832 );\r
d80ea739 833 if (!EFI_ERROR (Status)) {\r
834 //\r
835 // Open the Parent Handle for the child\r
836 //\r
837 Status = gBS->OpenProtocol (\r
838 Instance->Controller,\r
839 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
840 (VOID **) &MnpSb,\r
841 Instance->Image,\r
c22b6cdf 842 Instance->ChildHandle,\r
d80ea739 843 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
844 );\r
845 }\r
846\r
63886849 847 ASSERT_EFI_ERROR (Status);\r
c22b6cdf 848\r
d80ea739 849 //\r
850 // Publish our HII data\r
851 //\r
852 Instance->RegisteredHandle = HiiAddPackages (\r
853 &mNicIp4ConfigNvDataGuid,\r
854 Instance->ChildHandle,\r
855 Ip4ConfigDxeStrings,\r
856 Ip4ConfigDxeBin,\r
857 NULL\r
858 );\r
859 if (Instance->RegisteredHandle == NULL) {\r
860 return EFI_OUT_OF_RESOURCES;\r
861 }\r
862\r
863 //\r
864 // Append MAC string in the menu string and tile string\r
865 //\r
866 Status = NetLibGetMacString (Instance->Controller, Instance->Image, &MacString);\r
867 if (!EFI_ERROR (Status)) {\r
868 OldMenuString = HiiGetString (Instance->RegisteredHandle, STRING_TOKEN (STR_IP4_CONFIG_FORM_TITLE), NULL);\r
869 UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);\r
870 HiiSetString (Instance->RegisteredHandle, STRING_TOKEN (STR_IP4_CONFIG_FORM_TITLE), MenuString, NULL);\r
c22b6cdf 871\r
d80ea739 872 UnicodeSPrint (PortString, 128, L"MAC:%s", MacString);\r
873 HiiSetString (Instance->RegisteredHandle, STRING_TOKEN (STR_IP4_DEVICE_FORM_TITLE), PortString, NULL);\r
874 FreePool (MacString);\r
875 }\r
63886849 876\r
877 return Status;\r
878}\r
879\r
880/**\r
881 Uninstall HII Config Access protocol for network device and free resource.\r
882\r
883 @param[in] Instance The IP4 Config instance.\r
884\r
885 @retval EFI_SUCCESS The HII Config Access protocol is uninstalled.\r
886 @retval Others Other errors as indicated.\r
887**/\r
888EFI_STATUS\r
889Ip4ConfigDeviceUnload (\r
890 IN IP4_CONFIG_INSTANCE *Instance\r
891 )\r
892{\r
63886849 893 //\r
d80ea739 894 // Remove HII package list\r
63886849 895 //\r
d80ea739 896 HiiRemovePackages (Instance->RegisteredHandle);\r
63886849 897\r
898 //\r
d80ea739 899 // Close the child handle\r
63886849 900 //\r
d80ea739 901 gBS->CloseProtocol (\r
902 Instance->Controller,\r
903 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
904 Instance->Image,\r
905 Instance->ChildHandle\r
906 );\r
63886849 907\r
908 //\r
909 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
910 //\r
911 gBS->UninstallMultipleProtocolInterfaces (\r
d80ea739 912 Instance->ChildHandle,\r
63886849 913 &gEfiDevicePathProtocolGuid,\r
c22b6cdf 914 Instance->HiiVendorDevicePath,\r
63886849 915 &gEfiHiiConfigAccessProtocolGuid,\r
d80ea739 916 &Instance->HiiConfigAccessProtocol,\r
63886849 917 NULL\r
918 );\r
919\r
63886849 920 return EFI_SUCCESS;\r
921}\r