From: Fu Siyuan Date: Fri, 8 Jan 2016 02:38:34 +0000 (+0000) Subject: MdeModulePkg: Update MNP driver to recycle TX buffer asynchronously. X-Git-Tag: edk2-stable201903~8070 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=0507449955c5c629cec196b62986afbb91203ed9;hp=7b4b93a24790a3a802138d75167a8e55f3181d70 MdeModulePkg: Update MNP driver to recycle TX buffer asynchronously. This patch updates the MNP driver to recycle TX buffer asynchronously, instead of using a while loop wait after each transmit command. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Fu Siyuan Reviewed-by: Jiaxin Wu Reviewed-by: Ye Ting git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19624 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c index 046d4dfddc..d1a4cb5dd2 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c +++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpConfig.c @@ -1,7 +1,7 @@ /** @file Implementation of Managed Network Protocol private services. -Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.
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 @@ -209,6 +209,208 @@ MnpFreeNbuf ( gBS->RestoreTPL (OldTpl); } +/** + Add Count of TX buffers to MnpDeviceData->AllTxBufList and MnpDeviceData->FreeTxBufList. + The length of the buffer is specified by MnpDeviceData->BufferLength. + + @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA. + @param[in] Count Number of TX buffers to add. + + @retval EFI_SUCCESS The specified amount of TX buffers are allocated. + @retval EFI_OUT_OF_RESOURCES Failed to allocate a TX buffer. + +**/ +EFI_STATUS +MnpAddFreeTxBuf ( + IN OUT MNP_DEVICE_DATA *MnpDeviceData, + IN UINTN Count + ) +{ + EFI_STATUS Status; + UINT32 Index; + MNP_TX_BUF_WRAP *TxBufWrap; + + NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); + ASSERT ((Count > 0) && (MnpDeviceData->BufferLength > 0)); + + Status = EFI_SUCCESS; + for (Index = 0; Index < Count; Index++) { + TxBufWrap = (MNP_TX_BUF_WRAP*) AllocatePool (sizeof (MNP_TX_BUF_WRAP) + MnpDeviceData->BufferLength - 1); + if (TxBufWrap == NULL) { + DEBUG ((EFI_D_ERROR, "MnpAddFreeTxBuf: TxBuf Alloc failed.\n")); + + Status = EFI_OUT_OF_RESOURCES; + break; + } + DEBUG ((EFI_D_INFO, "MnpAddFreeTxBuf: Add TxBufWrap %p, TxBuf %p\n", TxBufWrap, TxBufWrap->TxBuf)); + TxBufWrap->Signature = MNP_TX_BUF_WRAP_SIGNATURE; + TxBufWrap->InUse = FALSE; + InsertTailList (&MnpDeviceData->FreeTxBufList, &TxBufWrap->WrapEntry); + InsertTailList (&MnpDeviceData->AllTxBufList, &TxBufWrap->AllEntry); + } + + MnpDeviceData->TxBufCount += Index; + return Status; +} + +/** + Allocate a free TX buffer from MnpDeviceData->FreeTxBufList. If there is none + in the queue, first try to recycle some from SNP, then try to allocate some and add + them into the queue, then fetch the NET_BUF from the updated FreeTxBufList. + + @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA. + + @return Pointer to the allocated free NET_BUF structure, if NULL the + operation is failed. + +**/ +UINT8 * +MnpAllocTxBuf ( + IN OUT MNP_DEVICE_DATA *MnpDeviceData + ) +{ + EFI_TPL OldTpl; + UINT8 *TxBuf; + EFI_STATUS Status; + LIST_ENTRY *Entry; + MNP_TX_BUF_WRAP *TxBufWrap; + + NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) { + // + // First try to recycle some TX buffer from SNP + // + Status = MnpRecycleTxBuf (MnpDeviceData); + if (EFI_ERROR (Status)) { + TxBuf = NULL; + goto ON_EXIT; + } + + // + // If still no free TX buffer, allocate more. + // + if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) { + if ((MnpDeviceData->TxBufCount + MNP_TX_BUFFER_INCREASEMENT) > MNP_MAX_TX_BUFFER_NUM) { + DEBUG ( + (EFI_D_ERROR, + "MnpAllocTxBuf: The maximum TxBuf size is reached for MNP driver instance %p.\n", + MnpDeviceData) + ); + + TxBuf = NULL; + goto ON_EXIT; + } + + Status = MnpAddFreeTxBuf (MnpDeviceData, MNP_TX_BUFFER_INCREASEMENT); + if (IsListEmpty (&MnpDeviceData->FreeTxBufList)) { + DEBUG ( + (EFI_D_ERROR, + "MnpAllocNbuf: Failed to add TxBuf into the FreeTxBufList, %r.\n", + Status) + ); + + TxBuf = NULL; + goto ON_EXIT; + } + } + } + + ASSERT (!IsListEmpty (&MnpDeviceData->FreeTxBufList)); + Entry = MnpDeviceData->FreeTxBufList.ForwardLink; + RemoveEntryList (MnpDeviceData->FreeTxBufList.ForwardLink); + TxBufWrap = NET_LIST_USER_STRUCT_S (Entry, MNP_TX_BUF_WRAP, WrapEntry, MNP_TX_BUF_WRAP_SIGNATURE); + TxBufWrap->InUse = TRUE; + TxBuf = TxBufWrap->TxBuf; + +ON_EXIT: + gBS->RestoreTPL (OldTpl); + + return TxBuf; +} + +/** + Try to reclaim the TX buffer into the buffer pool. + + @param[in, out] MnpDeviceData Pointer to the mnp device context data. + @param[in, out] TxBuf Pointer to the TX buffer to free. + +**/ +VOID +MnpFreeTxBuf ( + IN OUT MNP_DEVICE_DATA *MnpDeviceData, + IN OUT UINT8 *TxBuf + ) +{ + MNP_TX_BUF_WRAP *TxBufWrap; + EFI_TPL OldTpl; + + NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); + + if (TxBuf == NULL) { + return; + } + + TxBufWrap = NET_LIST_USER_STRUCT (TxBuf, MNP_TX_BUF_WRAP, TxBuf); + if (TxBufWrap->Signature != MNP_TX_BUF_WRAP_SIGNATURE) { + DEBUG ( + (EFI_D_ERROR, + "MnpFreeTxBuf: Signature check failed in MnpFreeTxBuf.\n") + ); + return; + } + + if (!TxBufWrap->InUse) { + DEBUG ( + (EFI_D_WARN, + "MnpFreeTxBuf: Duplicated recycle report from SNP.\n") + ); + return; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + InsertTailList (&MnpDeviceData->FreeTxBufList, &TxBufWrap->WrapEntry); + TxBufWrap->InUse = FALSE; + gBS->RestoreTPL (OldTpl); +} + +/** + Try to recycle all the transmitted buffer address from SNP. + + @param[in, out] MnpDeviceData Pointer to the mnp device context data. + + @retval EFI_SUCCESS Successed to recyclethe transmitted buffer address. + @retval Others Failed to recyclethe transmitted buffer address. + +**/ +EFI_STATUS +MnpRecycleTxBuf ( + IN OUT MNP_DEVICE_DATA *MnpDeviceData + ) +{ + UINT8 *TxBuf; + EFI_SIMPLE_NETWORK_PROTOCOL *Snp; + EFI_STATUS Status; + + Snp = MnpDeviceData->Snp; + ASSERT (Snp != NULL); + + do { + TxBuf = NULL; + Status = Snp->GetStatus (Snp, NULL, (VOID **) &TxBuf); + if (EFI_ERROR (Status)) { + return Status; + } + + if (TxBuf != NULL) { + MnpFreeTxBuf (MnpDeviceData, TxBuf); + } + } while (TxBuf != NULL); + + return EFI_SUCCESS; +} /** Initialize the mnp device context data. @@ -314,13 +516,9 @@ MnpInitializeDeviceData ( // // Allocate buffer pool for tx. // - MnpDeviceData->TxBuf = AllocatePool (MnpDeviceData->BufferLength); - if (MnpDeviceData->TxBuf == NULL) { - DEBUG ((EFI_D_ERROR, "MnpInitializeDeviceData: AllocatePool failed.\n")); - - Status = EFI_OUT_OF_RESOURCES; - goto ERROR; - } + InitializeListHead (&MnpDeviceData->FreeTxBufList); + InitializeListHead (&MnpDeviceData->AllTxBufList); + MnpDeviceData->TxBufCount = 0; // // Create the system poll timer. @@ -370,20 +568,6 @@ MnpInitializeDeviceData ( goto ERROR; } - // - // Create the timer for tx timeout check. - // - Status = gBS->CreateEvent ( - EVT_TIMER, - TPL_CALLBACK, - NULL, - NULL, - &MnpDeviceData->TxTimeoutEvent - ); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "MnpInitializeDeviceData: CreateEvent for tx timeout event failed.\n")); - } - ERROR: if (EFI_ERROR (Status)) { // @@ -405,10 +589,6 @@ ERROR: gBS->CloseEvent (MnpDeviceData->PollTimer); } - if (MnpDeviceData->TxBuf != NULL) { - FreePool (MnpDeviceData->TxBuf); - } - if (MnpDeviceData->RxNbufCache != NULL) { MnpFreeNbuf (MnpDeviceData, MnpDeviceData->RxNbufCache); } @@ -445,6 +625,10 @@ MnpDestroyDeviceData ( IN EFI_HANDLE ImageHandle ) { + LIST_ENTRY *Entry; + LIST_ENTRY *NextEntry; + MNP_TX_BUF_WRAP *TxBufWrap; + NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE); // @@ -462,15 +646,21 @@ MnpDestroyDeviceData ( // // Close the event. // - gBS->CloseEvent (MnpDeviceData->TxTimeoutEvent); gBS->CloseEvent (MnpDeviceData->TimeoutCheckTimer); gBS->CloseEvent (MnpDeviceData->MediaDetectTimer); gBS->CloseEvent (MnpDeviceData->PollTimer); // - // Free the tx buffer. + // Free the Tx buffer pool. // - FreePool (MnpDeviceData->TxBuf); + NET_LIST_FOR_EACH_SAFE(Entry, NextEntry, &MnpDeviceData->AllTxBufList) { + TxBufWrap = NET_LIST_USER_STRUCT (Entry, MNP_TX_BUF_WRAP, AllEntry); + RemoveEntryList (Entry); + FreePool (TxBufWrap); + MnpDeviceData->TxBufCount--; + } + ASSERT (IsListEmpty (&MnpDeviceData->AllTxBufList)); + ASSERT (MnpDeviceData->TxBufCount == 0); // // Free the RxNbufCache. @@ -957,7 +1147,7 @@ MnpStartSnp ( /** Stop the simple network. - @param[in] Snp Pointer to the simple network protocol. + @param[in] MnpDeviceData Pointer to the MNP_DEVICE_DATA. @retval EFI_SUCCESS The simple network is stopped. @retval Others Other errors as indicated. @@ -965,13 +1155,23 @@ MnpStartSnp ( **/ EFI_STATUS MnpStopSnp ( - IN EFI_SIMPLE_NETWORK_PROTOCOL *Snp + IN MNP_DEVICE_DATA *MnpDeviceData ) { EFI_STATUS Status; - + EFI_SIMPLE_NETWORK_PROTOCOL *Snp; + + Snp = MnpDeviceData->Snp; ASSERT (Snp != NULL); + // + // Recycle all the transmit buffer from SNP. + // + Status = MnpRecycleTxBuf (MnpDeviceData); + if (EFI_ERROR (Status)) { + return Status; + } + // // Shut down the simple network. // @@ -1162,7 +1362,7 @@ MnpStop ( // // Stop the simple network. // - Status = MnpStopSnp (MnpDeviceData->Snp); + Status = MnpStopSnp (MnpDeviceData); return Status; } diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h b/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h index 35a9b710db..126d968200 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h +++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.h @@ -1,7 +1,7 @@ /** @file Declaration of strctures and functions for MnpDxe driver. -Copyright (c) 2005 - 2012, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.
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 @@ -67,7 +67,9 @@ typedef struct { LIST_ENTRY GroupAddressList; UINT32 GroupAddressCount; - EFI_EVENT TxTimeoutEvent; + LIST_ENTRY FreeTxBufList; + LIST_ENTRY AllTxBufList; + UINT32 TxBufCount; NET_BUF_QUEUE FreeNbufQue; INTN NbufCnt; @@ -90,7 +92,6 @@ typedef struct { UINT32 BufferLength; UINT32 PaddingSize; NET_BUF *RxNbufCache; - UINT8 *TxBuf; } MNP_DEVICE_DATA; #define MNP_DEVICE_DATA_FROM_THIS(a) \ diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h b/MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h index f94e208306..c66be6487b 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h +++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpImpl.h @@ -1,7 +1,7 @@ /** @file Declaration of structures and functions of MnpDxe driver. -Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.
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 @@ -27,6 +27,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #define MNP_INIT_NET_BUFFER_NUM 512 #define MNP_NET_BUFFER_INCREASEMENT 64 #define MNP_MAX_NET_BUFFER_NUM 65536 +#define MNP_TX_BUFFER_INCREASEMENT 64 +#define MNP_MAX_TX_BUFFER_NUM 65536 #define MNP_MAX_RCVD_PACKET_QUE_SIZE 256 @@ -92,6 +94,15 @@ typedef struct { UINT64 TimeoutTick; } MNP_RXDATA_WRAP; +#define MNP_TX_BUF_WRAP_SIGNATURE SIGNATURE_32 ('M', 'T', 'B', 'W') + +typedef struct { + UINT32 Signature; + LIST_ENTRY WrapEntry; // Link to FreeTxBufList + LIST_ENTRY AllEntry; // Link to AllTxBufList + BOOLEAN InUse; + UINT8 TxBuf[1]; +} MNP_TX_BUF_WRAP; /** Initialize the mnp device context data. @@ -342,8 +353,11 @@ MnpIsValidTxToken ( @param[out] PktLen Pointer to a UINT32 variable used to record the packet's length. + @retval EFI_SUCCESS TxPackage is built. + @retval EFI_OUT_OF_RESOURCES The deliver fails due to lack of memory resource. + **/ -VOID +EFI_STATUS MnpBuildTxPacket ( IN MNP_SERVICE_DATA *MnpServiceData, IN EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData, @@ -352,7 +366,11 @@ MnpBuildTxPacket ( ); /** - Synchronously send out the packet. + Synchronously send out the packet. + + This functon places the packet buffer to SNP driver's tansmit queue. The packet + can be considered successfully sent out once SNP acccetp the packet, while the + packet buffer recycle is deferred for better performance. @param[in] MnpServiceData Pointer to the mnp service context data. @param[in] Packet Pointer to the pakcet buffer. @@ -448,6 +466,36 @@ MnpFreeNbuf ( IN OUT NET_BUF *Nbuf ); +/** + Allocate a free TX buffer from MnpDeviceData->FreeTxBufList. If there is none + in the queue, first try to recycle some from SNP, then try to allocate some and add + them into the queue, then fetch the NET_BUF from the updated FreeTxBufList. + + @param[in, out] MnpDeviceData Pointer to the MNP_DEVICE_DATA. + + @return Pointer to the allocated free NET_BUF structure, if NULL the + operation is failed. + +**/ +UINT8 * +MnpAllocTxBuf ( + IN OUT MNP_DEVICE_DATA *MnpDeviceData + ); + +/** + Try to recycle all the transmitted buffer address from SNP. + + @param[in, out] MnpDeviceData Pointer to the mnp device context data. + + @retval EFI_SUCCESS Successed to recyclethe transmitted buffer address. + @retval Others Failed to recyclethe transmitted buffer address. + +**/ +EFI_STATUS +MnpRecycleTxBuf ( + IN OUT MNP_DEVICE_DATA *MnpDeviceData + ); + /** Remove the received packets if timeout occurs. diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c index 7f03b848ef..1cbfc30e5c 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c +++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c @@ -1,7 +1,7 @@ /** @file Implementation of Managed Network Protocol I/O functions. -Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.
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 @@ -102,7 +102,6 @@ MnpIsValidTxToken ( return TRUE; } - /** Build the packet to transmit from the TxData passed in. @@ -113,8 +112,11 @@ MnpIsValidTxToken ( @param[out] PktLen Pointer to a UINT32 variable used to record the packet's length. + @retval EFI_SUCCESS TxPackage is built. + @retval EFI_OUT_OF_RESOURCES The deliver fails due to lack of memory resource. + **/ -VOID +EFI_STATUS MnpBuildTxPacket ( IN MNP_SERVICE_DATA *MnpServiceData, IN EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData, @@ -125,14 +127,24 @@ MnpBuildTxPacket ( EFI_SIMPLE_NETWORK_MODE *SnpMode; UINT8 *DstPos; UINT16 Index; - MNP_DEVICE_DATA *MnpDerviceData; - - MnpDerviceData = MnpServiceData->MnpDeviceData; - + MNP_DEVICE_DATA *MnpDeviceData; + UINT8 *TxBuf; + + MnpDeviceData = MnpServiceData->MnpDeviceData; + + TxBuf = MnpAllocTxBuf (MnpDeviceData); + if (TxBuf == NULL) { + return EFI_OUT_OF_RESOURCES; + } + // - // Reserve space for vlan tag. + // Reserve space for vlan tag if needed. // - *PktBuf = MnpDerviceData->TxBuf + NET_VLAN_TAG_LEN; + if (MnpServiceData->VlanId != 0) { + *PktBuf = TxBuf + NET_VLAN_TAG_LEN; + } else { + *PktBuf = TxBuf; + } if ((TxData->DestinationAddress == NULL) && (TxData->FragmentCount == 1)) { CopyMem ( @@ -148,7 +160,7 @@ MnpBuildTxPacket ( // one fragment, copy the data into the packet buffer. Reserve the // media header space if necessary. // - SnpMode = MnpDerviceData->Snp->Mode; + SnpMode = MnpDeviceData->Snp->Mode; DstPos = *PktBuf; *PktLen = 0; if (TxData->DestinationAddress != NULL) { @@ -177,11 +189,17 @@ MnpBuildTxPacket ( // *PktLen += TxData->DataLength + TxData->HeaderLength; } + + return EFI_SUCCESS; } /** - Synchronously send out the packet. + Synchronously send out the packet. + + This functon places the packet buffer to SNP driver's tansmit queue. The packet + can be considered successfully sent out once SNP acccetp the packet, while the + packet buffer recycle is deferred for better performance. @param[in] MnpServiceData Pointer to the mnp service context data. @param[in] Packet Pointer to the pakcet buffer. @@ -205,14 +223,13 @@ MnpSyncSendPacket ( EFI_SIMPLE_NETWORK_PROTOCOL *Snp; EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData; UINT32 HeaderSize; - UINT8 *TxBuf; MNP_DEVICE_DATA *MnpDeviceData; UINT16 ProtocolType; MnpDeviceData = MnpServiceData->MnpDeviceData; Snp = MnpDeviceData->Snp; TxData = Token->Packet.TxData; - + Token->Status = EFI_SUCCESS; HeaderSize = Snp->Mode->MediaHeaderSize - TxData->HeaderLength; // @@ -224,19 +241,7 @@ MnpSyncSendPacket ( // Media not present, skip packet transmit and report EFI_NO_MEDIA // DEBUG ((EFI_D_WARN, "MnpSyncSendPacket: No network cable detected.\n")); - Status = EFI_NO_MEDIA; - goto SIGNAL_TOKEN; - } - - // - // Start the timeout event. - // - Status = gBS->SetTimer ( - MnpDeviceData->TxTimeoutEvent, - TimerRelative, - MNP_TX_TIMEOUT_TIME - ); - if (EFI_ERROR (Status)) { + Token->Status = EFI_NO_MEDIA; goto SIGNAL_TOKEN; } @@ -250,10 +255,25 @@ MnpSyncSendPacket ( ProtocolType = TxData->ProtocolType; } - for (;;) { - // - // Transmit the packet through SNP. - // + // + // Transmit the packet through SNP. + // + Status = Snp->Transmit ( + Snp, + HeaderSize, + Length, + Packet, + TxData->SourceAddress, + TxData->DestinationAddress, + &ProtocolType + ); + if (Status == EFI_NOT_READY) { + Status = MnpRecycleTxBuf (MnpDeviceData); + if (EFI_ERROR (Status)) { + Token->Status = EFI_DEVICE_ERROR; + goto SIGNAL_TOKEN; + } + Status = Snp->Transmit ( Snp, HeaderSize, @@ -262,52 +282,15 @@ MnpSyncSendPacket ( TxData->SourceAddress, TxData->DestinationAddress, &ProtocolType - ); - if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_READY)) { - Status = EFI_DEVICE_ERROR; - break; - } - - // - // If Status is EFI_SUCCESS, the packet is put in the transmit queue. - // if Status is EFI_NOT_READY, the transmit engine of the network interface is busy. - // Both need to sync SNP. - // - TxBuf = NULL; - do { - // - // Get the recycled transmit buffer status. - // - Snp->GetStatus (Snp, NULL, (VOID **) &TxBuf); - - if (!EFI_ERROR (gBS->CheckEvent (MnpDeviceData->TxTimeoutEvent))) { - Status = EFI_TIMEOUT; - break; - } - } while (TxBuf == NULL); - - if ((Status == EFI_SUCCESS) || (Status == EFI_TIMEOUT)) { - break; - } else { - // - // Status is EFI_NOT_READY. Restart the timer event and call Snp->Transmit again. - // - gBS->SetTimer ( - MnpDeviceData->TxTimeoutEvent, - TimerRelative, - MNP_TX_TIMEOUT_TIME - ); - } + ); + } + + if (EFI_ERROR (Status)) { + Token->Status = EFI_DEVICE_ERROR; } - - // - // Cancel the timer event. - // - gBS->SetTimer (MnpDeviceData->TxTimeoutEvent, TimerCancel, 0); SIGNAL_TOKEN: - Token->Status = Status; gBS->SignalEvent (Token->Event); // diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpMain.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpMain.c index 4c0f3ddd9a..31c2e3e5b8 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/MnpMain.c +++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpMain.c @@ -1,7 +1,7 @@ /** @file Implementation of Managed Network Protocol public services. -Copyright (c) 2005 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.
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 @@ -552,7 +552,10 @@ MnpTransmit ( // // Build the tx packet // - MnpBuildTxPacket (MnpServiceData, Token->Packet.TxData, &PktBuf, &PktLen); + Status = MnpBuildTxPacket (MnpServiceData, Token->Packet.TxData, &PktBuf, &PktLen); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } // // OK, send the packet synchronously.