Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=886

This patch is to support the TFTP windowsize option described in RFC 7440.
The feature allows the client and server to negotiate a window size of
consecutive blocks to send as an alternative for replacing the single-block
lockstep schema.

Currently, the windowsize for write request operation is not supported since
there is no real use cases.

Cc: Ye Ting <ting...@intel.com>
Cc: Fu Siyuan <siyuan...@intel.com>
Cc: Shao Ming <ming.s...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Wu Jiaxin <jiaxin...@intel.com>
---
 .../Universal/Network/Mtftp4Dxe/Mtftp4Impl.c  |  5 ++
 .../Universal/Network/Mtftp4Dxe/Mtftp4Impl.h  | 10 ++++
 .../Network/Mtftp4Dxe/Mtftp4Option.c          | 25 ++++++++-
 .../Network/Mtftp4Dxe/Mtftp4Option.h          |  8 ++-
 .../Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c   | 55 +++++++++++++------
 .../Network/Mtftp4Dxe/Mtftp4Support.c         |  8 +--
 .../Network/Mtftp4Dxe/Mtftp4Support.h         | 13 -----
 .../Universal/Network/Mtftp4Dxe/Mtftp4Wrq.c   |  2 +-
 8 files changed, 89 insertions(+), 37 deletions(-)

diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c 
b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c
index 03903640b8..f442e6d7ac 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c
@@ -78,10 +78,13 @@ Mtftp4CleanOperation (
   ZeroMem (&Instance->RequestOption, sizeof (MTFTP4_OPTION));
 
   Instance->Operation     = 0;
 
   Instance->BlkSize       = MTFTP4_DEFAULT_BLKSIZE;
+  Instance->WindowSize    = 1;
+  Instance->TotalBlock    = 0;
+  Instance->AckedBlock    = 0;
   Instance->LastBlock     = 0;
   Instance->ServerIp      = 0;
   Instance->ListeningPort = 0;
   Instance->ConnectedPort = 0;
   Instance->Gateway       = 0;
@@ -426,10 +429,11 @@ Mtftp4Start (
   if (Token->OptionCount != 0) {
     Status = Mtftp4ParseOption (
                Token->OptionList,
                Token->OptionCount,
                TRUE,
+               Instance->Operation,
                &Instance->RequestOption
                );
 
     if (EFI_ERROR (Status)) {
       TokenStatus = EFI_DEVICE_ERROR;
@@ -441,10 +445,11 @@ Mtftp4Start (
   // Set the operation parameters from the configuration or override data.
   //
   Config                  = &Instance->Config;
   Instance->Token         = Token;
   Instance->BlkSize       = MTFTP4_DEFAULT_BLKSIZE;
+  Instance->WindowSize    = MTFTP4_DEFAULT_WINDOWSIZE;
 
   CopyMem (&Instance->ServerIp, &Config->ServerIp, sizeof (IP4_ADDR));
   Instance->ServerIp      = NTOHL (Instance->ServerIp);
 
   Instance->ListeningPort = Config->InitialServerPort;
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h 
b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h
index e24890cce8..de304f4e70 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.h
@@ -6,10 +6,11 @@
   RFC1350 - THE TFTP PROTOCOL (REVISION 2)
   RFC2090 - TFTP Multicast Option
   RFC2347 - TFTP Option Extension
   RFC2348 - TFTP Blocksize Option
   RFC2349 - TFTP Timeout Interval and Transfer Size Options
+  RFC7440 - TFTP Windowsize Option
 
 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD 
License
 which accompanies this distribution.  The full text of the license may be 
found at
@@ -54,10 +55,11 @@ typedef struct _MTFTP4_PROTOCOL MTFTP4_PROTOCOL;
 
 #define MTFTP4_DEFAULT_SERVER_PORT  69
 #define MTFTP4_DEFAULT_TIMEOUT      3
 #define MTFTP4_DEFAULT_RETRY        5
 #define MTFTP4_DEFAULT_BLKSIZE      512
+#define MTFTP4_DEFAULT_WINDOWSIZE   1
 #define MTFTP4_TIME_TO_GETMAP       5
 
 #define MTFTP4_STATE_UNCONFIGED     0
 #define MTFTP4_STATE_CONFIGED       1
 #define MTFTP4_STATE_DESTROY        2
@@ -119,10 +121,18 @@ struct _MTFTP4_PROTOCOL {
   //
   UINT16                        BlkSize;
   UINT16                        LastBlock;
   LIST_ENTRY                    Blocks;
 
+  UINT16                        WindowSize;
+
+  //
+  // Record the total received block number and the already acked block number.
+  //
+  UINT64                        TotalBlock;
+  UINT64                        AckedBlock;
+
   //
   // The server's communication end point: IP and two ports. one for
   // initial request, one for its selected port.
   //
   IP4_ADDR                      ServerIp;
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Option.c 
b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Option.c
index e40561a96b..2f77635268 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Option.c
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Option.c
@@ -1,9 +1,9 @@
 /** @file
   Routines to process MTFTP4 options.
 
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
 This program and the accompanying materials
 are licensed and made available under the terms and conditions of the BSD 
License
 which accompanies this distribution.  The full text of the license may be 
found at
 http://opensource.org/licenses/bsd-license.php<BR>
 
@@ -14,10 +14,11 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 
 #include "Mtftp4Impl.h"
 
 CHAR8 *mMtftp4SupportedOptions[MTFTP4_SUPPORTED_OPTIONS] = {
   "blksize",
+  "windowsize",
   "timeout",
   "tsize",
   "multicast"
 };
 
@@ -398,10 +399,11 @@ Mtftp4ExtractMcast (
   @param  Options                The option array, which contains addresses of 
each
                                  option's name/value string.
   @param  Count                  The number of options in the Options
   @param  Request                Whether this is a request or OACK. The format 
of
                                  multicast is different according to this 
setting.
+  @param  Operation              The current performed operation.
   @param  MtftpOption            The MTFTP4_OPTION for easy access.
 
   @retval EFI_INVALID_PARAMETER  The option is mal-formated
   @retval EFI_UNSUPPORTED        Some option isn't supported
   @retval EFI_SUCCESS            The option are OK and has been parsed.
@@ -410,10 +412,11 @@ Mtftp4ExtractMcast (
 EFI_STATUS
 Mtftp4ParseOption (
   IN     EFI_MTFTP4_OPTION     *Options,
   IN     UINT32                Count,
   IN     BOOLEAN               Request,
+  IN     UINT16                Operation,
      OUT MTFTP4_OPTION         *MtftpOption
   )
 {
   EFI_STATUS                Status;
   UINT32                    Index;
@@ -479,10 +482,26 @@ Mtftp4ParseOption (
         }
       }
 
       MtftpOption->Exist |= MTFTP4_MCAST_EXIST;
 
+    } else if (NetStringEqualNoCase (This->OptionStr, (UINT8 *) "windowsize")) 
{
+      if (Operation == EFI_MTFTP4_OPCODE_WRQ) {
+        //
+        // Currently, windowsize is not supported in the write operation.
+        //
+        return EFI_UNSUPPORTED;
+      }
+
+      Value = NetStringToU32 (This->ValueStr);
+
+      if (Value < 1) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      MtftpOption->WindowSize = (UINT16) Value;
+      MtftpOption->Exist |= MTFTP4_WINDOWSIZE_EXIST;
     } else if (Request) {
       //
       // Ignore the unsupported option if it is a reply, and return
       // EFI_UNSUPPORTED if it's a request according to the UEFI spec.
       //
@@ -498,10 +517,11 @@ Mtftp4ParseOption (
   Parse the options in the OACK packet to MTFTP4_OPTION which program
   can access directly.
 
   @param  Packet                 The OACK packet to parse
   @param  PacketLen              The length of the packet
+  @param  Operation              The current performed operation.
   @param  MtftpOption            The MTFTP_OPTION for easy access.
 
   @retval EFI_INVALID_PARAMETER  The packet option is mal-formated
   @retval EFI_UNSUPPORTED        Some option isn't supported
   @retval EFI_SUCCESS            The option are OK and has been parsed.
@@ -509,10 +529,11 @@ Mtftp4ParseOption (
 **/
 EFI_STATUS
 Mtftp4ParseOptionOack (
   IN     EFI_MTFTP4_PACKET     *Packet,
   IN     UINT32                PacketLen,
+  IN     UINT16                Operation,
      OUT MTFTP4_OPTION         *MtftpOption
   )
 {
   EFI_MTFTP4_OPTION *OptionList;
   EFI_STATUS        Status;
@@ -525,10 +546,10 @@ Mtftp4ParseOptionOack (
   if (EFI_ERROR (Status) || (Count == 0)) {
     return Status;
   }
   ASSERT (OptionList != NULL);
 
-  Status = Mtftp4ParseOption (OptionList, Count, FALSE, MtftpOption);
+  Status = Mtftp4ParseOption (OptionList, Count, FALSE, Operation, 
MtftpOption);
 
   FreePool (OptionList);
   return Status;
 }
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Option.h 
b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Option.h
index a3fdc4dca2..cb1f987b93 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Option.h
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Option.h
@@ -14,23 +14,25 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER 
EXPRESS OR IMPLIED.
 
 
 #ifndef __EFI_MTFTP4_OPTION_H__
 #define __EFI_MTFTP4_OPTION_H__
 
-#define MTFTP4_SUPPORTED_OPTIONS  4
+#define MTFTP4_SUPPORTED_OPTIONS  5
 #define MTFTP4_OPCODE_LEN         2
 #define MTFTP4_ERRCODE_LEN        2
 #define MTFTP4_BLKNO_LEN          2
 #define MTFTP4_DATA_HEAD_LEN      4
 
 #define MTFTP4_BLKSIZE_EXIST      0x01
 #define MTFTP4_TIMEOUT_EXIST      0x02
 #define MTFTP4_TSIZE_EXIST        0x04
 #define MTFTP4_MCAST_EXIST        0x08
+#define MTFTP4_WINDOWSIZE_EXIST   0x10
 
 typedef struct {
   UINT16                    BlkSize;
+  UINT16                    WindowSize;
   UINT8                     Timeout;
   UINT32                    Tsize;
   IP4_ADDR                  McastIp;
   UINT16                    McastPort;
   BOOLEAN                   Master;
@@ -69,10 +71,11 @@ Mtftp4ExtractOptions (
   @param  Options                The option array, which contains addresses of 
each
                                  option's name/value string.
   @param  Count                  The number of options in the Options
   @param  Request                Whether this is a request or OACK. The format 
of
                                  multicast is different according to this 
setting.
+  @param  Operation              The current performed operation.
   @param  MtftpOption            The MTFTP4_OPTION for easy access.
 
   @retval EFI_INVALID_PARAMETER  The option is mal-formated
   @retval EFI_UNSUPPORTED        Some option isn't supported
   @retval EFI_SUCCESS            The option are OK and has been parsed.
@@ -81,19 +84,21 @@ Mtftp4ExtractOptions (
 EFI_STATUS
 Mtftp4ParseOption (
   IN     EFI_MTFTP4_OPTION     *Options,
   IN     UINT32                Count,
   IN     BOOLEAN               Request,
+  IN     UINT16                Operation,
      OUT MTFTP4_OPTION         *MtftpOption
   );
 
 /**
   Parse the options in the OACK packet to MTFTP4_OPTION which program
   can access directly.
 
   @param  Packet                 The OACK packet to parse
   @param  PacketLen              The length of the packet
+  @param  Operation              The current performed operation.
   @param  MtftpOption            The MTFTP_OPTION for easy access.
 
   @retval EFI_INVALID_PARAMETER  The packet option is mal-formated
   @retval EFI_UNSUPPORTED        Some option isn't supported
   @retval EFI_SUCCESS            The option are OK and has been parsed.
@@ -101,10 +106,11 @@ Mtftp4ParseOption (
 **/
 EFI_STATUS
 Mtftp4ParseOptionOack (
   IN     EFI_MTFTP4_PACKET     *Packet,
   IN     UINT32                PacketLen,
+  IN     UINT16                Operation,
      OUT MTFTP4_OPTION         *MtftpOption
   );
 
 extern CHAR8  *mMtftp4SupportedOptions[MTFTP4_SUPPORTED_OPTIONS];
 
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c 
b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c
index 63115ba519..fedf1cde46 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c
@@ -97,10 +97,13 @@ Mtftp4RrqSendAck (
   IN UINT16                 BlkNo
   )
 {
   EFI_MTFTP4_PACKET         *Ack;
   NET_BUF                   *Packet;
+  EFI_STATUS                Status;
+
+  Status = EFI_SUCCESS;
 
   Packet = NetbufAlloc (sizeof (EFI_MTFTP4_ACK_HEADER));
   if (Packet == NULL) {
     return EFI_OUT_OF_RESOURCES;
   }
@@ -113,11 +116,16 @@ Mtftp4RrqSendAck (
   ASSERT (Ack != NULL);
 
   Ack->Ack.OpCode   = HTONS (EFI_MTFTP4_OPCODE_ACK);
   Ack->Ack.Block[0] = HTONS (BlkNo);
 
-  return Mtftp4SendPacket (Instance, Packet);
+  Status = Mtftp4SendPacket (Instance, Packet);
+  if (!EFI_ERROR (Status)) {
+    Instance->AckedBlock = Instance->TotalBlock;
+  }
+
+  return Status;
 }
 
 
 /**
   Deliver the received data block to the user, which can be saved
@@ -144,11 +152,10 @@ Mtftp4RrqSaveBlock (
   EFI_MTFTP4_TOKEN          *Token;
   EFI_STATUS                Status;
   UINT16                    Block;
   UINT64                    Start;
   UINT32                    DataLen;
-  UINT64                    TotalBlock;
   BOOLEAN                   Completed;
 
   Completed = FALSE;
   Token     = Instance->Token;
   Block     = NTOHS (Packet->Data.Block);
@@ -156,11 +163,11 @@ Mtftp4RrqSaveBlock (
 
   //
   // This is the last block, save the block no
   //
   if (DataLen < Instance->BlkSize) {
-  Completed = TRUE;
+    Completed = TRUE;
     Instance->LastBlock = Block;
     Mtftp4SetLastBlockNum (&Instance->Blocks, Block);
   }
 
   //
@@ -168,11 +175,11 @@ Mtftp4RrqSaveBlock (
   // returns EFI_NOT_FOUND, the block has been saved, don't save it again.
   // Note that : For bigger files, allowing the block counter to roll over
   // to accept transfers of unlimited size. So TotalBlock is memorised as
   // continuous block counter.
   //
-  Status = Mtftp4RemoveBlockNum (&Instance->Blocks, Block, Completed, 
&TotalBlock);
+  Status = Mtftp4RemoveBlockNum (&Instance->Blocks, Block, Completed, 
&Instance->TotalBlock);
 
   if (Status == EFI_NOT_FOUND) {
     return EFI_SUCCESS;
   } else if (EFI_ERROR (Status)) {
     return Status;
@@ -191,11 +198,11 @@ Mtftp4RrqSaveBlock (
       return EFI_ABORTED;
     }
   }
 
   if (Token->Buffer != NULL) {
-     Start = MultU64x32 (TotalBlock - 1, Instance->BlkSize);
+     Start = MultU64x32 (Instance->TotalBlock - 1, Instance->BlkSize);
 
     if (Start + DataLen <= Token->BufferSize) {
       CopyMem ((UINT8 *) Token->Buffer + Start, Packet->Data.Data, DataLen);
 
       //
@@ -255,23 +262,26 @@ Mtftp4RrqHandleData (
   EFI_STATUS                Status;
   UINT16                    BlockNum;
   INTN                      Expected;
 
   *Completed  = FALSE;
+  Status      = EFI_SUCCESS;
   BlockNum    = NTOHS (Packet->Data.Block);
   Expected    = Mtftp4GetNextBlockNum (&Instance->Blocks);
 
   ASSERT (Expected >= 0);
 
   //
-  // If we are active and received an unexpected packet, retransmit
-  // the last ACK then restart receiving. If we are passive, save
-  // the block.
+  // If we are active and received an unexpected packet, transmit
+  // the ACK for the block we received, then restart receiving the
+  // expected one. If we are passive, save the block.
   //
   if (Instance->Master && (Expected != BlockNum)) {
-    Mtftp4Retransmit (Instance);
-    return EFI_SUCCESS;
+    //
+    // If Expected is 0, (UINT16) (Expected - 1) is also the expected Ack 
number (65535).
+    //
+    return Mtftp4RrqSendAck (Instance,  (UINT16) (Expected - 1));
   }
 
   Status = Mtftp4RrqSaveBlock (Instance, Packet, Len);
 
   if (EFI_ERROR (Status)) {
@@ -307,14 +317,17 @@ Mtftp4RrqHandleData (
 
     } else {
       BlockNum = (UINT16) (Expected - 1);
     }
 
-    Mtftp4RrqSendAck (Instance, BlockNum);
+    if (Instance->WindowSize == (Instance->TotalBlock - Instance->AckedBlock) 
|| Expected < 0) {
+      Status = Mtftp4RrqSendAck (Instance, BlockNum);
+    }
+
   }
 
-  return EFI_SUCCESS;
+  return Status;
 }
 
 
 /**
   Validate whether the options received in the server's OACK packet is valid.
@@ -347,15 +360,17 @@ Mtftp4RrqOackValid (
   if ((Reply->Exist &~Request->Exist) != 0) {
     return FALSE;
   }
 
   //
-  // Server can only specify a smaller block size to be used and
+  // Server can only specify a smaller block size and window size to be used 
and
   // return the timeout matches that requested.
   //
   if ((((Reply->Exist & MTFTP4_BLKSIZE_EXIST) != 0)&& (Reply->BlkSize > 
Request->BlkSize)) ||
-      (((Reply->Exist & MTFTP4_TIMEOUT_EXIST) != 0) && (Reply->Timeout != 
Request->Timeout))) {
+      (((Reply->Exist & MTFTP4_WINDOWSIZE_EXIST) != 0)&& (Reply->WindowSize > 
Request->WindowSize)) ||
+      (((Reply->Exist & MTFTP4_TIMEOUT_EXIST) != 0) && (Reply->Timeout != 
Request->Timeout))
+     ) {
     return FALSE;
   }
 
   //
   // The server can send ",,master" to client to change its master
@@ -505,11 +520,11 @@ Mtftp4RrqHandleOack (
   //
   // Parse and validate the options from server
   //
   ZeroMem (&Reply, sizeof (MTFTP4_OPTION));
 
-  Status = Mtftp4ParseOptionOack (Packet, Len, &Reply);
+  Status = Mtftp4ParseOptionOack (Packet, Len, Instance->Operation, &Reply);
 
   if (EFI_ERROR (Status) ||
       !Mtftp4RrqOackValid (Instance, &Reply, &Instance->RequestOption)) {
     //
     // Don't send an ERROR packet if the error is EFI_OUT_OF_RESOURCES.
@@ -527,11 +542,11 @@ Mtftp4RrqHandleOack (
 
   if ((Reply.Exist & MTFTP4_MCAST_EXIST) != 0) {
 
     //
     // Save the multicast info. Always update the Master, only update the
-    // multicast IP address, block size, timeoute at the first time. If IP
+    // multicast IP address, block size, window size, timeoute at the first 
time. If IP
     // address is updated, create a UDP child to receive the multicast.
     //
     Instance->Master = Reply.Master;
 
     if (Instance->McastIp == 0) {
@@ -597,10 +612,14 @@ Mtftp4RrqHandleOack (
       //
       if (Reply.BlkSize != 0) {
         Instance->BlkSize = Reply.BlkSize;
       }
 
+      if (Reply.WindowSize != 0) {
+        Instance->WindowSize = Reply.WindowSize;
+      }
+
       if (Reply.Timeout != 0) {
         Instance->Timeout = Reply.Timeout;
       }
     }
 
@@ -609,10 +628,14 @@ Mtftp4RrqHandleOack (
 
     if (Reply.BlkSize != 0) {
       Instance->BlkSize = Reply.BlkSize;
     }
 
+    if (Reply.WindowSize != 0) {
+      Instance->WindowSize = Reply.WindowSize;
+    }
+
     if (Reply.Timeout != 0) {
       Instance->Timeout = Reply.Timeout;
     }
   }
 
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c 
b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c
index 71c679ed13..71fd979b3a 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c
@@ -218,19 +218,19 @@ Mtftp4RemoveBlockNum (
       // transfers of unlimited size. There is no consensus, however, whether
       // the counter should wrap around to zero or to one. Many implementations
       // wrap to zero, because this is the simplest to implement. Here we 
choose
       // this solution.
       //
-    *TotalBlock  = Num;
+      *TotalBlock  = Num;
 
       if (Range->Round > 0) {
-      *TotalBlock += Range->Bound +  MultU64x32 ((UINTN) (Range->Round -1), 
(UINT32) (Range->Bound + 1)) + 1;
-    }
+        *TotalBlock += Range->Bound +  MultU64x32 ((UINTN) (Range->Round -1), 
(UINT32) (Range->Bound + 1)) + 1;
+      }
 
       if (Range->Start > Range->Bound) {
         Range->Start = 0;
-      Range->Round ++;
+        Range->Round ++;
       }
 
       if ((Range->Start > Range->End) || Completed) {
         RemoveEntryList (&Range->Link);
         FreePool (Range);
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.h 
b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.h
index df18440a9e..6cc2756bc8 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.h
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.h
@@ -171,23 +171,10 @@ Mtftp4SendError (
   IN MTFTP4_PROTOCOL        *Instance,
   IN UINT16                 ErrCode,
   IN UINT8                  *ErrInfo
   );
 
-/**
-  Retransmit the last packet for the instance.
-
-  @param  Instance              The Mtftp instance
-
-  @retval EFI_SUCCESS           The last packet is retransmitted.
-  @retval Others                Failed to retransmit.
-
-**/
-EFI_STATUS
-Mtftp4Retransmit (
-  IN MTFTP4_PROTOCOL        *Instance
-  );
 
 /**
   The timer ticking function in TPL_NOTIFY level for the Mtftp service 
instance.
 
   @param  Event                 The ticking event
diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Wrq.c 
b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Wrq.c
index cf1d50fe40..ea309e2d6b 100644
--- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Wrq.c
+++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Wrq.c
@@ -284,11 +284,11 @@ Mtftp4WrqHandleOack (
 
   //
   // Parse and validate the options from server
   //
   ZeroMem (&Reply, sizeof (MTFTP4_OPTION));
-  Status = Mtftp4ParseOptionOack (Packet, Len, &Reply);
+  Status = Mtftp4ParseOptionOack (Packet, Len, Instance->Operation, &Reply);
 
   if (EFI_ERROR (Status) || !Mtftp4WrqOackValid (&Reply, 
&Instance->RequestOption)) {
     //
     // Don't send a MTFTP error packet when out of resource, it can
     // only make it worse.
-- 
2.17.1.windows.2

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to