2 Mtftp6 Rrq process functions implementation.
4 Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "Mtftp6Impl.h"
14 Build and send a ACK packet for download.
16 @param[in] Instance The pointer to the Mtftp6 instance.
17 @param[in] BlockNum The block number to be acked.
19 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the packet.
20 @retval EFI_SUCCESS The ACK has been sent.
21 @retval Others Failed to send the ACK.
26 IN MTFTP6_INSTANCE
*Instance
,
30 EFI_MTFTP6_PACKET
*Ack
;
37 // Allocate net buffer to create ack packet.
39 Packet
= NetbufAlloc (sizeof (EFI_MTFTP6_ACK_HEADER
));
42 return EFI_OUT_OF_RESOURCES
;
45 Ack
= (EFI_MTFTP6_PACKET
*) NetbufAllocSpace (
47 sizeof (EFI_MTFTP6_ACK_HEADER
),
52 Ack
->Ack
.OpCode
= HTONS (EFI_MTFTP6_OPCODE_ACK
);
53 Ack
->Ack
.Block
[0] = HTONS (BlockNum
);
56 // Reset current retry count of the instance.
58 Instance
->CurRetry
= 0;
59 Instance
->LastPacket
= Packet
;
61 Status
= Mtftp6TransmitPacket (Instance
, Packet
);
62 if (!EFI_ERROR (Status
)) {
63 Instance
->AckedBlock
= Instance
->TotalBlock
;
71 Deliver the received data block to the user, which can be saved
72 in the user provide buffer or through the CheckPacket callback.
74 @param[in] Instance The pointer to the Mtftp6 instance.
75 @param[in] Packet The pointer to the received packet.
76 @param[in] Len The packet length.
77 @param[out] UdpPacket The net buf of the received packet.
79 @retval EFI_SUCCESS The data was saved successfully.
80 @retval EFI_ABORTED The user tells to abort by return an error through
82 @retval EFI_BUFFER_TOO_SMALL The user's buffer is too small, and buffer length is
83 updated to the actual buffer size needed.
88 IN MTFTP6_INSTANCE
*Instance
,
89 IN EFI_MTFTP6_PACKET
*Packet
,
91 OUT NET_BUF
**UdpPacket
94 EFI_MTFTP6_TOKEN
*Token
;
103 Token
= Instance
->Token
;
104 Block
= NTOHS (Packet
->Data
.Block
);
105 DataLen
= Len
- MTFTP6_DATA_HEAD_LEN
;
108 // This is the last block, save the block num
110 if (DataLen
< Instance
->BlkSize
) {
112 Instance
->LastBlk
= Block
;
113 Mtftp6SetLastBlockNum (&Instance
->BlkList
, Block
);
117 // Remove this block number from the file hole. If Mtftp6RemoveBlockNum
118 // returns EFI_NOT_FOUND, the block has been saved, don't save it again.
119 // Note that : For bigger files, allowing the block counter to roll over
120 // to accept transfers of unlimited size. So BlockCounter is memorised as
121 // continuous block counter.
123 Status
= Mtftp6RemoveBlockNum (&Instance
->BlkList
, Block
, Completed
, &BlockCounter
);
125 if (Status
== EFI_NOT_FOUND
) {
127 } else if (EFI_ERROR (Status
)) {
131 if (Token
->CheckPacket
!= NULL
) {
133 // Callback to the check packet routine with the received packet.
135 Status
= Token
->CheckPacket (&Instance
->Mtftp6
, Token
, (UINT16
) Len
, Packet
);
137 if (EFI_ERROR (Status
)) {
139 // Free the received packet before send new packet in ReceiveNotify,
140 // since the Udp6Io might need to be reconfigured.
142 NetbufFree (*UdpPacket
);
145 // Send the Mtftp6 error message if user aborted the current session.
149 EFI_MTFTP6_ERRORCODE_ILLEGAL_OPERATION
,
150 (UINT8
*) "User aborted download"
157 if (Token
->Buffer
!= NULL
) {
159 Start
= MultU64x32 (BlockCounter
- 1, Instance
->BlkSize
);
160 if (Start
+ DataLen
<= Token
->BufferSize
) {
161 CopyMem ((UINT8
*) Token
->Buffer
+ Start
, Packet
->Data
.Data
, DataLen
);
163 // Update the file size when received the last block
165 if ((Instance
->LastBlk
== Block
) && Completed
) {
166 Token
->BufferSize
= Start
+ DataLen
;
168 } else if (Instance
->LastBlk
!= 0) {
170 // Don't save the data if the buffer is too small, return
171 // EFI_BUFFER_TOO_SMALL if received the last packet. This
172 // will give a accurate file length.
174 Token
->BufferSize
= Start
+ DataLen
;
177 // Free the received packet before send new packet in ReceiveNotify,
178 // since the udpio might need to be reconfigured.
180 NetbufFree (*UdpPacket
);
183 // Send the Mtftp6 error message if no enough buffer.
187 EFI_MTFTP6_ERRORCODE_DISK_FULL
,
188 (UINT8
*) "User provided memory block is too small"
191 return EFI_BUFFER_TOO_SMALL
;
200 Process the received data packets. It will save the block
201 then send back an ACK if it is active.
203 @param[in] Instance The pointer to the Mtftp6 instance.
204 @param[in] Packet The pointer to the received packet.
205 @param[in] Len The length of the packet.
206 @param[out] UdpPacket The net buf of received packet.
207 @param[out] IsCompleted If TRUE, the download has been completed.
208 Otherwise, the download has not been completed.
210 @retval EFI_SUCCESS The data packet was successfully processed.
211 @retval EFI_ABORTED The download was aborted by the user.
212 @retval EFI_BUFFER_TOO_SMALL The user-provided buffer is too small.
216 Mtftp6RrqHandleData (
217 IN MTFTP6_INSTANCE
*Instance
,
218 IN EFI_MTFTP6_PACKET
*Packet
,
220 OUT NET_BUF
**UdpPacket
,
221 OUT BOOLEAN
*IsCompleted
228 *IsCompleted
= FALSE
;
229 Status
= EFI_SUCCESS
;
230 BlockNum
= NTOHS (Packet
->Data
.Block
);
231 Expected
= Mtftp6GetNextBlockNum (&Instance
->BlkList
);
233 ASSERT (Expected
>= 0);
236 // If we are active (Master) and received an unexpected packet, transmit
237 // the ACK for the block we received, then restart receiving the
238 // expected one. If we are passive (Slave), save the block.
240 if (Instance
->IsMaster
&& (Expected
!= BlockNum
)) {
242 // Free the received packet before send new packet in ReceiveNotify,
243 // since the udpio might need to be reconfigured.
245 NetbufFree (*UdpPacket
);
249 // If Expected is 0, (UINT16) (Expected - 1) is also the expected Ack number (65535).
251 return Mtftp6RrqSendAck (Instance
, (UINT16
) (Expected
- 1));
254 Status
= Mtftp6RrqSaveBlock (Instance
, Packet
, Len
, UdpPacket
);
256 if (EFI_ERROR (Status
)) {
261 // Record the total received and saved block number.
263 Instance
->TotalBlock
++;
266 // Reset the passive client's timer whenever it received a valid data packet.
268 if (!Instance
->IsMaster
) {
269 Instance
->PacketToLive
= Instance
->Timeout
* 2;
273 // Check whether we have received all the blocks. Send the ACK if we
274 // are active (unicast client or master client for multicast download).
275 // If we have received all the blocks, send an ACK even if we are passive
276 // to tell the server that we are done.
278 Expected
= Mtftp6GetNextBlockNum (&Instance
->BlkList
);
280 if (Instance
->IsMaster
|| Expected
< 0) {
283 // If we are passive client, then the just received Block maybe
284 // isn't the last block. We need to send an ACK to the last block
285 // to inform the server that we are done. If we are active client,
286 // the Block == Instance->LastBlock.
288 BlockNum
= Instance
->LastBlk
;
292 BlockNum
= (UINT16
) (Expected
- 1);
295 // Free the received packet before send new packet in ReceiveNotify,
296 // since the udpio might need to be reconfigured.
298 NetbufFree (*UdpPacket
);
301 if (Instance
->WindowSize
== (Instance
->TotalBlock
- Instance
->AckedBlock
) || Expected
< 0) {
302 Status
= Mtftp6RrqSendAck (Instance
, BlockNum
);
311 Validate whether the options received in the server's OACK packet is valid.
312 The options are valid only if:
313 1. The server doesn't include options not requested by us.
314 2. The server can only use smaller blksize than that is requested.
315 3. The server can only use the same timeout as requested.
316 4. The server doesn't change its multicast channel.
318 @param[in] Instance The pointer to the Mtftp6 instance.
319 @param[in] ReplyInfo The pointer to options information in reply packet.
320 @param[in] RequestInfo The pointer to requested options info.
322 @retval TRUE If the option in the OACK is valid.
323 @retval FALSE If the option is invalid.
328 IN MTFTP6_INSTANCE
*Instance
,
329 IN MTFTP6_EXT_OPTION_INFO
*ReplyInfo
,
330 IN MTFTP6_EXT_OPTION_INFO
*RequestInfo
334 // It is invalid for server to return options we don't request
336 if ((ReplyInfo
->BitMap
& ~RequestInfo
->BitMap
) != 0) {
341 // Server can only specify a smaller block size and windowsize to be used and
342 // return the timeout matches that requested.
344 if ((((ReplyInfo
->BitMap
& MTFTP6_OPT_BLKSIZE_BIT
) != 0) && (ReplyInfo
->BlkSize
> RequestInfo
->BlkSize
)) ||
345 (((ReplyInfo
->BitMap
& MTFTP6_OPT_WINDOWSIZE_BIT
) != 0) && (ReplyInfo
->BlkSize
> RequestInfo
->BlkSize
)) ||
346 (((ReplyInfo
->BitMap
& MTFTP6_OPT_TIMEOUT_BIT
) != 0) && (ReplyInfo
->Timeout
!= RequestInfo
->Timeout
))
352 // The server can send ",,master" to client to change its master
353 // setting. But if it use the specific multicast channel, it can't
354 // change the setting.
356 if (((ReplyInfo
->BitMap
& MTFTP6_OPT_MCAST_BIT
) != 0) && !NetIp6IsUnspecifiedAddr (&Instance
->McastIp
)) {
358 if (!NetIp6IsUnspecifiedAddr (&ReplyInfo
->McastIp
) && CompareMem (
361 sizeof (EFI_IPv6_ADDRESS
)
366 if ((ReplyInfo
->McastPort
!= 0) && (ReplyInfo
->McastPort
!= Instance
->McastPort
)) {
376 Configure Udp6Io to receive a packet from a multicast address.
378 @param[in] McastIo The pointer to the mcast Udp6Io.
379 @param[in] Context The pointer to the context.
381 @retval EFI_SUCCESS The mcast Udp6Io was successfully configured.
382 @retval Others Failed to configure the Udp6Io.
387 Mtftp6RrqConfigMcastUdpIo (
393 EFI_UDP6_PROTOCOL
*Udp6
;
394 EFI_UDP6_CONFIG_DATA
*Udp6Cfg
;
395 EFI_IPv6_ADDRESS Group
;
396 MTFTP6_INSTANCE
*Instance
;
398 Udp6
= McastIo
->Protocol
.Udp6
;
399 Udp6Cfg
= &(McastIo
->Config
.Udp6
);
400 Instance
= (MTFTP6_INSTANCE
*) Context
;
403 // Set the configure data for the mcast Udp6Io.
405 ZeroMem (Udp6Cfg
, sizeof (EFI_UDP6_CONFIG_DATA
));
407 Udp6Cfg
->AcceptPromiscuous
= FALSE
;
408 Udp6Cfg
->AcceptAnyPort
= FALSE
;
409 Udp6Cfg
->AllowDuplicatePort
= FALSE
;
410 Udp6Cfg
->TrafficClass
= 0;
411 Udp6Cfg
->HopLimit
= 128;
412 Udp6Cfg
->ReceiveTimeout
= 0;
413 Udp6Cfg
->TransmitTimeout
= 0;
414 Udp6Cfg
->StationPort
= Instance
->McastPort
;
415 Udp6Cfg
->RemotePort
= 0;
418 &Udp6Cfg
->RemoteAddress
,
420 sizeof (EFI_IPv6_ADDRESS
)
424 // Configure the mcast Udp6Io.
426 Status
= Udp6
->Configure (Udp6
, Udp6Cfg
);
428 if (EFI_ERROR (Status
)) {
433 // Join the multicast group
435 CopyMem (&Group
, &Instance
->McastIp
, sizeof (EFI_IPv6_ADDRESS
));
437 return Udp6
->Groups (Udp6
, TRUE
, &Group
);
442 Process the OACK packet for Rrq.
444 @param[in] Instance The pointer to the Mtftp6 instance.
445 @param[in] Packet The pointer to the received packet.
446 @param[in] Len The length of the packet.
447 @param[out] UdpPacket The net buf of received packet.
448 @param[out] IsCompleted If TRUE, the download has been completed.
449 Otherwise, the download has not been completed.
451 @retval EFI_DEVICE_ERROR Failed to create/start a multicast Udp6 child.
452 @retval EFI_TFTP_ERROR An error happened during the process.
453 @retval EFI_SUCCESS The OACK packet successfully processed.
457 Mtftp6RrqHandleOack (
458 IN MTFTP6_INSTANCE
*Instance
,
459 IN EFI_MTFTP6_PACKET
*Packet
,
461 OUT NET_BUF
**UdpPacket
,
462 OUT BOOLEAN
*IsCompleted
465 EFI_MTFTP6_OPTION
*Options
;
467 MTFTP6_EXT_OPTION_INFO ExtInfo
;
470 EFI_UDP6_PROTOCOL
*Udp6
;
472 *IsCompleted
= FALSE
;
476 // If already started the master download, don't change the
477 // setting. Master download always succeeds.
479 Expected
= Mtftp6GetNextBlockNum (&Instance
->BlkList
);
480 ASSERT (Expected
!= -1);
482 if (Instance
->IsMaster
&& Expected
!= 1) {
486 ZeroMem (&ExtInfo
, sizeof (MTFTP6_EXT_OPTION_INFO
));
489 // Parse the options in the packet.
491 Status
= Mtftp6ParseStart (Packet
, Len
, &Count
, &Options
);
493 if (EFI_ERROR (Status
)) {
496 ASSERT (Options
!= NULL
);
499 // Parse the extensive options in the packet.
501 Status
= Mtftp6ParseExtensionOption (Options
, Count
, FALSE
, Instance
->Operation
, &ExtInfo
);
503 if (EFI_ERROR (Status
) || !Mtftp6RrqOackValid (Instance
, &ExtInfo
, &Instance
->ExtInfo
)) {
505 // Don't send an ERROR packet if the error is EFI_OUT_OF_RESOURCES.
507 if (Status
!= EFI_OUT_OF_RESOURCES
) {
509 // Free the received packet before send new packet in ReceiveNotify,
510 // since the udpio might need to be reconfigured.
512 NetbufFree (*UdpPacket
);
515 // Send the Mtftp6 error message if invalid packet.
519 EFI_MTFTP6_ERRORCODE_ILLEGAL_OPERATION
,
520 (UINT8
*) "Mal-formated OACK packet"
524 return EFI_TFTP_ERROR
;
527 if ((ExtInfo
.BitMap
& MTFTP6_OPT_MCAST_BIT
) != 0) {
530 // Save the multicast info. Always update the Master, only update the
531 // multicast IP address, block size, window size, timeoute at the first time. If IP
532 // address is updated, create a UDP child to receive the multicast.
534 Instance
->IsMaster
= ExtInfo
.IsMaster
;
536 if (NetIp6IsUnspecifiedAddr (&Instance
->McastIp
)) {
537 if (NetIp6IsUnspecifiedAddr (&ExtInfo
.McastIp
) || ExtInfo
.McastPort
== 0) {
539 // Free the received packet before send new packet in ReceiveNotify,
540 // since the udpio might need to be reconfigured.
542 NetbufFree (*UdpPacket
);
545 // Send the Mtftp6 error message if invalid multi-cast setting.
549 EFI_MTFTP6_ERRORCODE_ILLEGAL_OPERATION
,
550 (UINT8
*) "Illegal multicast setting"
553 return EFI_TFTP_ERROR
;
557 // Create a UDP child then start receive the multicast from it.
562 sizeof (EFI_IP_ADDRESS
)
565 Instance
->McastPort
= ExtInfo
.McastPort
;
566 if (Instance
->McastUdpIo
== NULL
) {
567 Instance
->McastUdpIo
= UdpIoCreateIo (
568 Instance
->Service
->Controller
,
569 Instance
->Service
->Image
,
570 Mtftp6RrqConfigMcastUdpIo
,
574 if (Instance
->McastUdpIo
!= NULL
) {
575 Status
= gBS
->OpenProtocol (
576 Instance
->McastUdpIo
->UdpHandle
,
577 &gEfiUdp6ProtocolGuid
,
579 Instance
->Service
->Image
,
581 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
583 if (EFI_ERROR (Status
)) {
584 UdpIoFreeIo (Instance
->McastUdpIo
);
585 Instance
->McastUdpIo
= NULL
;
586 return EFI_DEVICE_ERROR
;
591 if (Instance
->McastUdpIo
== NULL
) {
592 return EFI_DEVICE_ERROR
;
595 Status
= UdpIoRecvDatagram (
596 Instance
->McastUdpIo
,
602 if (EFI_ERROR (Status
)) {
604 // Free the received packet before send new packet in ReceiveNotify,
605 // since the udpio might need to be reconfigured.
607 NetbufFree (*UdpPacket
);
610 // Send the Mtftp6 error message if failed to create Udp6Io to receive.
614 EFI_MTFTP6_ERRORCODE_ACCESS_VIOLATION
,
615 (UINT8
*) "Failed to create socket to receive multicast packet"
622 // Update the parameters used.
624 if (ExtInfo
.BlkSize
!= 0) {
625 Instance
->BlkSize
= ExtInfo
.BlkSize
;
628 if (ExtInfo
.WindowSize
!= 0) {
629 Instance
->WindowSize
= ExtInfo
.WindowSize
;
632 if (ExtInfo
.Timeout
!= 0) {
633 Instance
->Timeout
= ExtInfo
.Timeout
;
639 Instance
->IsMaster
= TRUE
;
641 if (ExtInfo
.BlkSize
!= 0) {
642 Instance
->BlkSize
= ExtInfo
.BlkSize
;
645 if (ExtInfo
.WindowSize
!= 0) {
646 Instance
->WindowSize
= ExtInfo
.WindowSize
;
649 if (ExtInfo
.Timeout
!= 0) {
650 Instance
->Timeout
= ExtInfo
.Timeout
;
655 // Free the received packet before send new packet in ReceiveNotify,
656 // since the udpio might need to be reconfigured.
658 NetbufFree (*UdpPacket
);
661 // Send an ACK to (Expected - 1) which is 0 for unicast download,
662 // or tell the server we want to receive the Expected block.
664 return Mtftp6RrqSendAck (Instance
, (UINT16
) (Expected
- 1));
669 The packet process callback for Mtftp6 download.
671 @param[in] UdpPacket The pointer to the packet received.
672 @param[in] UdpEpt The pointer to the Udp6 access point.
673 @param[in] IoStatus The status from Udp6 instance.
674 @param[in] Context The pointer to the context.
680 IN NET_BUF
*UdpPacket
,
681 IN UDP_END_POINT
*UdpEpt
,
682 IN EFI_STATUS IoStatus
,
686 MTFTP6_INSTANCE
*Instance
;
687 EFI_MTFTP6_PACKET
*Packet
;
695 Instance
= (MTFTP6_INSTANCE
*) Context
;
697 NET_CHECK_SIGNATURE (Instance
, MTFTP6_INSTANCE_SIGNATURE
);
699 Status
= EFI_SUCCESS
;
706 // Return error status if Udp6 instance failed to receive.
708 if (EFI_ERROR (IoStatus
)) {
713 ASSERT (UdpPacket
!= NULL
);
715 if (UdpPacket
->TotalSize
< MTFTP6_OPCODE_LEN
) {
720 // Find the port this packet is from to restart receive correctly.
723 Ip6Swap128 (&UdpEpt
->LocalAddr
.v6
),
725 sizeof (EFI_IPv6_ADDRESS
)
733 // Client send initial request to server's listening port. Server
734 // will select a UDP port to communicate with the client. The server
735 // is required to use the same port as RemotePort to multicast the
738 if (UdpEpt
->RemotePort
!= Instance
->ServerDataPort
) {
739 if (Instance
->ServerDataPort
!= 0) {
743 // For the subsequent exchange of requests, reconfigure the udpio as
744 // (serverip, serverport, localip, localport).
745 // Ususally, the client set serverport as 0 to receive and reset it
746 // once the first packet arrives to send ack.
748 Instance
->ServerDataPort
= UdpEpt
->RemotePort
;
753 // Copy the MTFTP packet to a continuous buffer if it isn't already so.
755 Len
= UdpPacket
->TotalSize
;
756 TotalNum
= UdpPacket
->BlockOpNum
;
759 Packet
= AllocateZeroPool (Len
);
761 if (Packet
== NULL
) {
762 Status
= EFI_OUT_OF_RESOURCES
;
766 NetbufCopy (UdpPacket
, 0, Len
, (UINT8
*) Packet
);
769 Packet
= (EFI_MTFTP6_PACKET
*) NetbufGetByte (UdpPacket
, 0, NULL
);
770 ASSERT (Packet
!= NULL
);
773 Opcode
= NTOHS (Packet
->OpCode
);
776 // Callback to the user's CheckPacket if provided. Abort the transmission
777 // if CheckPacket returns an EFI_ERROR code.
779 if ((Instance
->Token
->CheckPacket
!= NULL
) &&
780 (Opcode
== EFI_MTFTP6_OPCODE_OACK
|| Opcode
== EFI_MTFTP6_OPCODE_ERROR
)
783 Status
= Instance
->Token
->CheckPacket (
790 if (EFI_ERROR (Status
)) {
792 // Send an error message to the server to inform it
794 if (Opcode
!= EFI_MTFTP6_OPCODE_ERROR
) {
796 // Free the received packet before send new packet in ReceiveNotify,
797 // since the udpio might need to be reconfigured.
799 NetbufFree (UdpPacket
);
802 // Send the Mtftp6 error message if user aborted the current session.
806 EFI_MTFTP6_ERRORCODE_REQUEST_DENIED
,
807 (UINT8
*) "User aborted the transfer"
811 Status
= EFI_ABORTED
;
817 // Switch the process routines by the operation code.
820 case EFI_MTFTP6_OPCODE_DATA
:
821 if ((Len
> (UINT32
) (MTFTP6_DATA_HEAD_LEN
+ Instance
->BlkSize
)) || (Len
< (UINT32
) MTFTP6_DATA_HEAD_LEN
)) {
825 // Handle the data packet of Rrq.
827 Status
= Mtftp6RrqHandleData (
836 case EFI_MTFTP6_OPCODE_OACK
:
837 if (IsMcast
|| Len
<= MTFTP6_OPCODE_LEN
) {
841 // Handle the Oack packet of Rrq.
843 Status
= Mtftp6RrqHandleOack (
854 // Drop and return eror if received error message.
856 Status
= EFI_TFTP_ERROR
;
862 // Free the resources, then if !EFI_ERROR (Status), restart the
863 // receive, otherwise end the session.
865 if (Packet
!= NULL
&& TotalNum
> 1) {
868 if (UdpPacket
!= NULL
) {
869 NetbufFree (UdpPacket
);
871 if (!EFI_ERROR (Status
) && !IsCompleted
) {
873 Status
= UdpIoRecvDatagram (
874 Instance
->McastUdpIo
,
880 Status
= UdpIoRecvDatagram (
889 // Clean up the current session if failed to continue.
891 if (EFI_ERROR (Status
) || IsCompleted
) {
892 Mtftp6OperationClean (Instance
, Status
);
898 Start the Mtftp6 instance to download. It first initializes some
899 of the internal states, then builds and sends an RRQ reqeuest packet.
900 Finally, it starts receive for the downloading.
902 @param[in] Instance The pointer to the Mtftp6 instance.
903 @param[in] Operation The operation code of current packet.
905 @retval EFI_SUCCESS The Mtftp6 is started to download.
906 @retval Others Failed to start to download.
911 IN MTFTP6_INSTANCE
*Instance
,
918 // The valid block number range are [1, 0xffff]. For example:
919 // the client sends an RRQ request to the server, the server
920 // transfers the DATA1 block. If option negoitation is ongoing,
921 // the server will send back an OACK, then client will send ACK0.
923 Status
= Mtftp6InitBlockRange (&Instance
->BlkList
, 1, 0xffff);
925 if (EFI_ERROR (Status
)) {
929 Status
= Mtftp6SendRequest (Instance
, Operation
);
931 if (EFI_ERROR (Status
)) {
935 return UdpIoRecvDatagram (