X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FNetwork%2FMnpDxe%2FMnpIo.c;h=56405d62b5e05b1b1f9f6b743576b32301f539ec;hp=695873d2f63c7226eaf59b2b73070749242f8f9b;hb=c0fd7f734e2d33e22215899b40a47b843129541d;hpb=412d1ed9fcfa169548993acb7b2bc4ffb0b77649
diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c
index 695873d2f6..56405d62b5 100644
--- a/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c
+++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c
@@ -1,15 +1,8 @@
/** @file
Implementation of Managed Network Protocol I/O functions.
-Copyright (c) 2005 - 2010, 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
-text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -102,7 +95,6 @@ MnpIsValidTxToken (
return TRUE;
}
-
/**
Build the packet to transmit from the TxData passed in.
@@ -113,8 +105,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,15 +120,32 @@ MnpBuildTxPacket (
EFI_SIMPLE_NETWORK_MODE *SnpMode;
UINT8 *DstPos;
UINT16 Index;
- MNP_DEVICE_DATA *MnpDerviceData;
+ 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 if needed.
+ //
+ if (MnpServiceData->VlanId != 0) {
+ *PktBuf = TxBuf + NET_VLAN_TAG_LEN;
+ } else {
+ *PktBuf = TxBuf;
+ }
- MnpDerviceData = MnpServiceData->MnpDeviceData;
if ((TxData->DestinationAddress == NULL) && (TxData->FragmentCount == 1)) {
- //
- // Media header is in FragmentTable and there is only one fragment,
- // use fragment buffer directly.
- //
- *PktBuf = TxData->FragmentTable[0].FragmentBuffer;
+ CopyMem (
+ *PktBuf,
+ TxData->FragmentTable[0].FragmentBuffer,
+ TxData->FragmentTable[0].FragmentLength
+ );
+
*PktLen = TxData->FragmentTable[0].FragmentLength;
} else {
//
@@ -141,9 +153,8 @@ MnpBuildTxPacket (
// one fragment, copy the data into the packet buffer. Reserve the
// media header space if necessary.
//
- SnpMode = MnpDerviceData->Snp->Mode;
- DstPos = MnpDerviceData->TxBuf;
-
+ SnpMode = MnpDeviceData->Snp->Mode;
+ DstPos = *PktBuf;
*PktLen = 0;
if (TxData->DestinationAddress != NULL) {
//
@@ -167,17 +178,22 @@ MnpBuildTxPacket (
}
//
- // Set the buffer pointer and the buffer length.
+ // Set the buffer length.
//
- *PktBuf = MnpDerviceData->TxBuf;
*PktLen += TxData->DataLength + TxData->HeaderLength;
}
+
+ return EFI_SUCCESS;
}
/**
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.
@param[in] Length The length of the packet.
@@ -200,14 +216,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;
//
@@ -219,31 +234,39 @@ 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;
+ Token->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)) {
- goto SIGNAL_TOKEN;
+
+ if (MnpServiceData->VlanId != 0) {
+ //
+ // Insert VLAN tag
+ //
+ MnpInsertVlanTag (MnpServiceData, TxData, &ProtocolType, &Packet, &Length);
+ } else {
+ ProtocolType = TxData->ProtocolType;
}
//
- // Insert VLAN tag
+ // Transmit the packet through SNP.
//
- MnpInsertVlanTag (MnpServiceData, TxData, &ProtocolType, &Packet, &Length);
+ 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;
+ }
- for (;;) {
- //
- // Transmit the packet through SNP.
- //
Status = Snp->Transmit (
Snp,
HeaderSize,
@@ -253,51 +276,14 @@ MnpSyncSendPacket (
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
- );
- }
}
- //
- // Cancel the timer event.
- //
- gBS->SetTimer (MnpDeviceData->TxTimeoutEvent, TimerCancel, 0);
+ if (EFI_ERROR (Status)) {
+ Token->Status = EFI_DEVICE_ERROR;
+ }
SIGNAL_TOKEN:
- Token->Status = Status;
gBS->SignalEvent (Token->Event);
//
@@ -890,7 +876,7 @@ MnpReceivePacket (
if (MnpDeviceData->RxNbufCache == NULL) {
//
- // No availabe buffer in the buffer pool.
+ // No available buffer in the buffer pool.
//
return EFI_DEVICE_ERROR;
}
@@ -944,7 +930,14 @@ MnpReceivePacket (
}
VlanId = 0;
- IsVlanPacket = MnpRemoveVlanTag (MnpDeviceData, Nbuf, &VlanId);
+ if (MnpDeviceData->NumberOfVlan != 0) {
+ //
+ // VLAN is configured, remove the VLAN tag if any
+ //
+ IsVlanPacket = MnpRemoveVlanTag (MnpDeviceData, Nbuf, &VlanId);
+ } else {
+ IsVlanPacket = FALSE;
+ }
MnpServiceData = MnpFindServiceData (MnpDeviceData, VlanId);
if (MnpServiceData == NULL) {