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) {