+/**\r
+ Initializes, changes, or resets the default operational setting for this\r
+ EFI MTFTPv4 Protocol driver instance.\r
+\r
+ The Configure() function is used to set and change the configuration data for\r
+ this EFI MTFTPv4 Protocol driver instance. The configuration data can be reset\r
+ to startup defaults by calling Configure() with MtftpConfigData set to NULL.\r
+ Whenever the instance is reset, any pending operation is aborted. By changing\r
+ the EFI MTFTPv4 Protocol driver instance configuration data, the client can\r
+ connect to different MTFTPv4 servers. The configuration parameters in\r
+ MtftpConfigData are used as the default parameters in later MTFTPv4 operations\r
+ and can be overridden in later operations.\r
+\r
+ @param This Pointer to the EFI_MTFTP4_PROTOCOL instance\r
+ @param ConfigData MtftpConfigDataPointer to the configuration data\r
+ structure\r
+\r
+ @retval EFI_SUCCESS The EFI MTFTPv4 Protocol driver was configured\r
+ successfully.\r
+ @retval EFI_INVALID_PARAMETER One or more following conditions are TRUE:\r
+ 1.This is NULL.\r
+ 2.MtftpConfigData.UseDefaultSetting is FALSE and\r
+ MtftpConfigData.StationIp is not a valid IPv4\r
+ unicast address.\r
+ 3.MtftpCofigData.UseDefaultSetting is FALSE and\r
+ MtftpConfigData.SubnetMask is invalid.\r
+ 4.MtftpCofigData.ServerIp is not a valid IPv4\r
+ unicast address.\r
+ 5.MtftpConfigData.UseDefaultSetting is FALSE and\r
+ MtftpConfigData.GatewayIp is not a valid IPv4\r
+ unicast address or is not in the same subnet\r
+ with station address.\r
+ @retval EFI_ACCESS_DENIED The EFI configuration could not be changed at this\r
+ time because there is one MTFTP background operation\r
+ in progress.\r
+ @retval EFI_NO_MAPPING When using a default address, configuration\r
+ (DHCP, BOOTP, RARP, etc.) has not finished yet.\r
+ @retval EFI_UNSUPPORTED A configuration protocol (DHCP, BOOTP, RARP, etc.)\r
+ could not be located when clients choose to use\r
+ the default address settings.\r
+ @retval EFI_OUT_OF_RESOURCES The EFI MTFTPv4 Protocol driver instance data could\r
+ not be allocated.\r
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
+ The EFI MTFTPv4 Protocol driver instance is not\r
+ configured.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiMtftp4Configure (\r
+ IN EFI_MTFTP4_PROTOCOL *This,\r
+ IN EFI_MTFTP4_CONFIG_DATA *ConfigData\r
+ )\r
+{\r
+ MTFTP4_PROTOCOL *Instance;\r
+ EFI_TPL OldTpl;\r
+ IP4_ADDR Ip;\r
+ IP4_ADDR Netmask;\r
+ IP4_ADDR Gateway;\r
+ IP4_ADDR ServerIp;\r
+\r
+ if (This == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Instance = MTFTP4_PROTOCOL_FROM_THIS (This);\r
+\r
+ if (ConfigData == NULL) {\r
+ //\r
+ // Reset the operation if ConfigData is NULL\r
+ //\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+ Mtftp4CleanOperation (Instance, EFI_ABORTED);\r
+ ZeroMem (&Instance->Config, sizeof (EFI_MTFTP4_CONFIG_DATA));\r
+ Instance->State = MTFTP4_STATE_UNCONFIGED;\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
+\r
+ } else {\r
+ //\r
+ // Configure the parameters for new operation.\r
+ //\r
+ CopyMem (&Ip, &ConfigData->StationIp, sizeof (IP4_ADDR));\r
+ CopyMem (&Netmask, &ConfigData->SubnetMask, sizeof (IP4_ADDR));\r
+ CopyMem (&Gateway, &ConfigData->GatewayIp, sizeof (IP4_ADDR));\r
+ CopyMem (&ServerIp, &ConfigData->ServerIp, sizeof (IP4_ADDR));\r
+\r
+ Ip = NTOHL (Ip);\r
+ Netmask = NTOHL (Netmask);\r
+ Gateway = NTOHL (Gateway);\r
+ ServerIp = NTOHL (ServerIp);\r
+\r
+ if (ServerIp == 0 || IP4_IS_LOCAL_BROADCAST (ServerIp)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (!ConfigData->UseDefaultSetting &&\r
+ ((!IP4_IS_VALID_NETMASK (Netmask) || (Netmask != 0 && !NetIp4IsUnicast (Ip, Netmask))))) {\r
+\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if ((Gateway != 0) &&\r
+ ((Netmask != 0xFFFFFFFF && !IP4_NET_EQUAL (Gateway, Ip, Netmask)) || (Netmask != 0 && !NetIp4IsUnicast (Gateway, Netmask)))) {\r
+\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+\r
+ if ((Instance->State == MTFTP4_STATE_CONFIGED) && (Instance->Operation != 0)) {\r
+ gBS->RestoreTPL (OldTpl);\r
+ return EFI_ACCESS_DENIED;\r
+ }\r
+\r
+ CopyMem(&Instance->Config, ConfigData, sizeof (*ConfigData));;\r
+ Instance->State = MTFTP4_STATE_CONFIGED;\r
+\r
+ gBS->RestoreTPL (OldTpl);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+\r
+/**\r
+ Parses the options in an MTFTPv4 OACK packet.\r
+\r
+ The ParseOptions() function parses the option fields in an MTFTPv4 OACK packet\r
+ and returns the number of options that were found and optionally a list of\r
+ pointers to the options in the packet.\r
+ If one or more of the option fields are not valid, then EFI_PROTOCOL_ERROR is\r
+ returned and *OptionCount and *OptionList stop at the last valid option.\r
+ The OptionList is allocated by this function, and caller should free it when used.\r
+\r
+ @param This Pointer to the EFI_MTFTP4_PROTOCOL instance.\r
+ @param PacketLen Length of the OACK packet to be parsed.\r
+ @param Packet Pointer to the OACK packet to be parsed.\r
+ @param OptionCount Pointer to the number of options in following OptionList.\r
+ @param OptionList Pointer to EFI_MTFTP4_OPTION storage. Call the\r
+ EFI Boot Service FreePool() to release theOptionList\r
+ if the options in this OptionList are not needed\r
+ any more\r
+\r
+ @retval EFI_SUCCESS The OACK packet was valid and the OptionCount and\r
+ OptionList parameters have been updated.\r
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
+ 1.PacketLen is 0.\r
+ 2.Packet is NULL or Packet is not a valid MTFTPv4 packet.\r
+ 3.OptionCount is NULL.\r
+ @retval EFI_NOT_FOUND No options were found in the OACK packet.\r
+ @retval EFI_OUT_OF_RESOURCES Storage for the OptionList array cannot be allocated.\r
+ @retval EFI_PROTOCOL_ERROR One or more of the option fields is invalid.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EfiMtftp4ParseOptions (\r
+ IN EFI_MTFTP4_PROTOCOL *This,\r
+ IN UINT32 PacketLen,\r
+ IN EFI_MTFTP4_PACKET *Packet,\r
+ OUT UINT32 *OptionCount,\r
+ OUT EFI_MTFTP4_OPTION **OptionList OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ if ((This == NULL) || (PacketLen < MTFTP4_OPCODE_LEN) ||\r
+ (Packet == NULL) || (OptionCount == NULL)) {\r
+\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Status = Mtftp4ExtractOptions (Packet, PacketLen, OptionCount, OptionList);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (*OptionCount == 0) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Downloads a file from an MTFTPv4 server.\r
+\r
+ The ReadFile() function is used to initialize and start an MTFTPv4 download\r
+ process and optionally wait for completion. When the download operation completes,\r
+ whether successfully or not, the Token.Status field is updated by the EFI MTFTPv4\r
+ Protocol driver and then Token.Event is signaled (if it is not NULL).\r
+ Data can be downloaded from the MTFTPv4 server into either of the following locations:\r
+ 1.A fixed buffer that is pointed to by Token.Buffer\r
+ 2.A download service function that is pointed to by Token.CheckPacket\r
+ If both Token.Buffer and Token.CheckPacket are used, then Token.CheckPacket\r
+ will be called first. If the call is successful, the packet will be stored in\r
+ Token.Buffer.\r
+\r
+ @param This Pointer to the EFI_MTFTP4_PROTOCOL instance\r
+ @param Token Pointer to the token structure to provide the\r
+ parameters that are used in this operation.\r
+\r
+ @retval EFI_SUCCESS The data file has been transferred successfully.\r
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.\r
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is not large enough to hold the downloaded\r
+ data in downloading process.\r
+ @retval EFI_ABORTED Current operation is aborted by user.\r
+ @retval EFI_ICMP_ERROR An ICMP ERROR packet was received.\r
+ @retval EFI_TIMEOUT No responses were received from the MTFTPv4 server.\r
+ @retval EFI_TFTP_ERROR An MTFTPv4 ERROR packet was received.\r
+ @retval EFI_DEVICE_ERROR An unexpected network error or system error occurred.\r
+ @retval EFI_NO_MEDIA There was a media error.\r