X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FNetwork%2FMnpDxe%2FMnpIo.c;h=1cbfc30e5c21128e8c44fb382fe866ce5c44d5aa;hp=8cc7db8ad27934e92f4646f8a2340d98d2eb7a6b;hb=0507449955c5c629cec196b62986afbb91203ed9;hpb=766c7483c335931b190a78d78d62e5a5e69dc8b9
diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c
index 8cc7db8ad2..1cbfc30e5c 100644
--- a/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c
+++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c
@@ -1,10 +1,11 @@
/** @file
Implementation of Managed Network Protocol I/O functions.
-
-Copyright (c) 2005 - 2009, 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
+
+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
+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,
@@ -13,6 +14,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "MnpImpl.h"
+#include "MnpVlan.h"
/**
Validates the Mnp transmit token.
@@ -25,8 +27,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
BOOLEAN
MnpIsValidTxToken (
- IN MNP_INSTANCE_DATA *Instance,
- IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
+ IN MNP_INSTANCE_DATA *Instance,
+ IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
)
{
MNP_SERVICE_DATA *MnpServiceData;
@@ -38,7 +40,7 @@ MnpIsValidTxToken (
MnpServiceData = Instance->MnpServiceData;
NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
- TxData = Token->Packet.TxData;
+ TxData = Token->Packet.TxData;
if ((Token->Event == NULL) || (TxData == NULL) || (TxData->FragmentCount == 0)) {
//
@@ -100,36 +102,57 @@ MnpIsValidTxToken (
return TRUE;
}
-
/**
Build the packet to transmit from the TxData passed in.
@param[in] MnpServiceData Pointer to the mnp service context data.
- @param[in] TxData Pointer to the transmit data containing the information
+ @param[in] TxData Pointer to the transmit data containing the information
to build the packet.
@param[out] PktBuf Pointer to record the address of the packet.
- @param[out] PktLen Pointer to a UINT32 variable used to record the packet's
+ @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,
- OUT UINT8 **PktBuf,
- OUT UINT32 *PktLen
+ IN MNP_SERVICE_DATA *MnpServiceData,
+ IN EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData,
+ OUT UINT8 **PktBuf,
+ OUT UINT32 *PktLen
)
{
EFI_SIMPLE_NETWORK_MODE *SnpMode;
UINT8 *DstPos;
UINT16 Index;
-
+ 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;
+ }
+
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 {
//
@@ -137,9 +160,8 @@ MnpBuildTxPacket (
// one fragment, copy the data into the packet buffer. Reserve the
// media header space if necessary.
//
- SnpMode = MnpServiceData->Snp->Mode;
- DstPos = MnpServiceData->TxBuf;
-
+ SnpMode = MnpDeviceData->Snp->Mode;
+ DstPos = *PktBuf;
*PktLen = 0;
if (TxData->DestinationAddress != NULL) {
//
@@ -163,16 +185,21 @@ MnpBuildTxPacket (
}
//
- // Set the buffer pointer and the buffer length.
+ // Set the buffer length.
//
- *PktBuf = MnpServiceData->TxBuf;
*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.
@@ -186,40 +213,67 @@ MnpBuildTxPacket (
**/
EFI_STATUS
MnpSyncSendPacket (
- IN MNP_SERVICE_DATA *MnpServiceData,
- IN UINT8 *Packet,
- IN UINT32 Length,
- IN OUT EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
+ IN MNP_SERVICE_DATA *MnpServiceData,
+ IN UINT8 *Packet,
+ IN UINT32 Length,
+ IN OUT EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
)
{
EFI_STATUS Status;
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData;
UINT32 HeaderSize;
- UINT8 *TxBuf;
-
- Snp = MnpServiceData->Snp;
- TxData = Token->Packet.TxData;
+ MNP_DEVICE_DATA *MnpDeviceData;
+ UINT16 ProtocolType;
- HeaderSize = Snp->Mode->MediaHeaderSize - TxData->HeaderLength;
+ MnpDeviceData = MnpServiceData->MnpDeviceData;
+ Snp = MnpDeviceData->Snp;
+ TxData = Token->Packet.TxData;
+ Token->Status = EFI_SUCCESS;
+ HeaderSize = Snp->Mode->MediaHeaderSize - TxData->HeaderLength;
//
- // Start the timeout event.
+ // Check media status before transmit packet.
+ // Note: media status will be updated by periodic timer MediaDetectTimer.
//
- Status = gBS->SetTimer (
- MnpServiceData->TxTimeoutEvent,
- TimerRelative,
- MNP_TX_TIMEOUT_TIME
- );
- if (EFI_ERROR (Status)) {
-
+ if (Snp->Mode->MediaPresentSupported && !Snp->Mode->MediaPresent) {
+ //
+ // Media not present, skip packet transmit and report EFI_NO_MEDIA
+ //
+ DEBUG ((EFI_D_WARN, "MnpSyncSendPacket: No network cable detected.\n"));
+ Token->Status = EFI_NO_MEDIA;
goto SIGNAL_TOKEN;
}
- for (;;) {
+
+ if (MnpServiceData->VlanId != 0) {
//
- // Transmit the packet through SNP.
+ // Insert VLAN tag
//
+ MnpInsertVlanTag (MnpServiceData, TxData, &ProtocolType, &Packet, &Length);
+ } else {
+ ProtocolType = TxData->ProtocolType;
+ }
+
+ //
+ // 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,
@@ -227,56 +281,16 @@ MnpSyncSendPacket (
Packet,
TxData->SourceAddress,
TxData->DestinationAddress,
- &TxData->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 (MnpServiceData->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 (
- MnpServiceData->TxTimeoutEvent,
- TimerRelative,
- MNP_TX_TIMEOUT_TIME
- );
- }
+ &ProtocolType
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ Token->Status = EFI_DEVICE_ERROR;
}
-
- //
- // Cancel the timer event.
- //
- gBS->SetTimer (MnpServiceData->TxTimeoutEvent, TimerCancel, 0);
SIGNAL_TOKEN:
- Token->Status = Status;
gBS->SignalEvent (Token->Event);
//
@@ -301,18 +315,18 @@ SIGNAL_TOKEN:
**/
EFI_STATUS
MnpInstanceDeliverPacket (
- IN OUT MNP_INSTANCE_DATA *Instance
+ IN OUT MNP_INSTANCE_DATA *Instance
)
{
- MNP_SERVICE_DATA *MnpServiceData;
+ MNP_DEVICE_DATA *MnpDeviceData;
MNP_RXDATA_WRAP *RxDataWrap;
NET_BUF *DupNbuf;
EFI_MANAGED_NETWORK_RECEIVE_DATA *RxData;
EFI_SIMPLE_NETWORK_MODE *SnpMode;
EFI_MANAGED_NETWORK_COMPLETION_TOKEN *RxToken;
- MnpServiceData = Instance->MnpServiceData;
- NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
+ MnpDeviceData = Instance->MnpServiceData->MnpDeviceData;
+ NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
if (NetMapIsEmpty (&Instance->RxTokenMap) || IsListEmpty (&Instance->RcvdPacketQueue)) {
//
@@ -329,7 +343,7 @@ MnpInstanceDeliverPacket (
// There are other instances share this Nbuf, duplicate to get a
// copy to allow the instance to do R/W operations.
//
- DupNbuf = MnpAllocNbuf (MnpServiceData);
+ DupNbuf = MnpAllocNbuf (MnpDeviceData);
if (DupNbuf == NULL) {
DEBUG ((EFI_D_WARN, "MnpDeliverPacket: Failed to allocate a free Nbuf.\n"));
@@ -340,7 +354,7 @@ MnpInstanceDeliverPacket (
// Duplicate the net buffer.
//
NetbufDuplicate (RxDataWrap->Nbuf, DupNbuf, 0);
- MnpFreeNbuf (MnpServiceData, RxDataWrap->Nbuf);
+ MnpFreeNbuf (MnpDeviceData, RxDataWrap->Nbuf);
RxDataWrap->Nbuf = DupNbuf;
}
@@ -351,7 +365,7 @@ MnpInstanceDeliverPacket (
Instance->RcvdPacketQueueSize--;
RxData = &RxDataWrap->RxData;
- SnpMode = MnpServiceData->Snp->Mode;
+ SnpMode = MnpDeviceData->Snp->Mode;
//
// Set all the buffer pointers.
@@ -390,7 +404,7 @@ MnpInstanceDeliverPacket (
**/
VOID
MnpDeliverPacket (
- IN MNP_SERVICE_DATA *MnpServiceData
+ IN MNP_SERVICE_DATA *MnpServiceData
)
{
LIST_ENTRY *Entry;
@@ -421,12 +435,12 @@ MnpDeliverPacket (
VOID
EFIAPI
MnpRecycleRxData (
- IN EFI_EVENT Event,
- IN VOID *Context
+ IN EFI_EVENT Event,
+ IN VOID *Context
)
{
- MNP_RXDATA_WRAP *RxDataWrap;
- MNP_SERVICE_DATA *MnpServiceData;
+ MNP_RXDATA_WRAP *RxDataWrap;
+ MNP_DEVICE_DATA *MnpDeviceData;
ASSERT (Context != NULL);
@@ -435,13 +449,13 @@ MnpRecycleRxData (
ASSERT (RxDataWrap->Nbuf != NULL);
- MnpServiceData = RxDataWrap->Instance->MnpServiceData;
- NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
+ MnpDeviceData = RxDataWrap->Instance->MnpServiceData->MnpDeviceData;
+ NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
//
// Free this Nbuf.
//
- MnpFreeNbuf (MnpServiceData, RxDataWrap->Nbuf);
+ MnpFreeNbuf (MnpDeviceData, RxDataWrap->Nbuf);
RxDataWrap->Nbuf = NULL;
//
@@ -467,8 +481,8 @@ MnpRecycleRxData (
**/
VOID
MnpQueueRcvdPacket (
- IN OUT MNP_INSTANCE_DATA *Instance,
- IN OUT MNP_RXDATA_WRAP *RxDataWrap
+ IN OUT MNP_INSTANCE_DATA *Instance,
+ IN OUT MNP_RXDATA_WRAP *RxDataWrap
)
{
MNP_RXDATA_WRAP *OldRxDataWrap;
@@ -528,10 +542,10 @@ MnpQueueRcvdPacket (
**/
BOOLEAN
MnpMatchPacket (
- IN MNP_INSTANCE_DATA *Instance,
- IN EFI_MANAGED_NETWORK_RECEIVE_DATA *RxData,
- IN MNP_GROUP_ADDRESS *GroupAddress OPTIONAL,
- IN UINT8 PktAttr
+ IN MNP_INSTANCE_DATA *Instance,
+ IN EFI_MANAGED_NETWORK_RECEIVE_DATA *RxData,
+ IN MNP_GROUP_ADDRESS *GroupAddress OPTIONAL,
+ IN UINT8 PktAttr
)
{
EFI_MANAGED_NETWORK_CONFIG_DATA *ConfigData;
@@ -607,18 +621,20 @@ MnpMatchPacket (
**/
VOID
MnpAnalysePacket (
- IN MNP_SERVICE_DATA *MnpServiceData,
- IN NET_BUF *Nbuf,
- IN OUT EFI_MANAGED_NETWORK_RECEIVE_DATA *RxData,
- OUT MNP_GROUP_ADDRESS **GroupAddress,
- OUT UINT8 *PktAttr
+ IN MNP_SERVICE_DATA *MnpServiceData,
+ IN NET_BUF *Nbuf,
+ IN OUT EFI_MANAGED_NETWORK_RECEIVE_DATA *RxData,
+ OUT MNP_GROUP_ADDRESS **GroupAddress,
+ OUT UINT8 *PktAttr
)
{
EFI_SIMPLE_NETWORK_MODE *SnpMode;
+ MNP_DEVICE_DATA *MnpDeviceData;
UINT8 *BufPtr;
LIST_ENTRY *Entry;
- SnpMode = MnpServiceData->Snp->Mode;
+ MnpDeviceData = MnpServiceData->MnpDeviceData;
+ SnpMode = MnpDeviceData->Snp->Mode;
//
// Get the packet buffer.
@@ -650,7 +666,7 @@ MnpAnalysePacket (
//
// It's multicast, try to match the multicast filters.
//
- NET_LIST_FOR_EACH (Entry, &MnpServiceData->GroupAddressList) {
+ NET_LIST_FOR_EACH (Entry, &MnpDeviceData->GroupAddressList) {
*GroupAddress = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_ADDRESS, AddrEntry);
if (NET_MAC_EQUAL (BufPtr, &((*GroupAddress)->Address), SnpMode->HwAddressSize)) {
@@ -667,7 +683,7 @@ MnpAnalysePacket (
*GroupAddress = NULL;
RxData->PromiscuousFlag = TRUE;
- if (MnpServiceData->PromiscuousCount == 0) {
+ if (MnpDeviceData->PromiscuousCount == 0) {
//
// Skip the below code, there is no receiver of this packet.
//
@@ -703,8 +719,8 @@ MnpAnalysePacket (
**/
MNP_RXDATA_WRAP *
MnpWrapRxData (
- IN MNP_INSTANCE_DATA *Instance,
- IN EFI_MANAGED_NETWORK_RECEIVE_DATA *RxData
+ IN MNP_INSTANCE_DATA *Instance,
+ IN EFI_MANAGED_NETWORK_RECEIVE_DATA *RxData
)
{
EFI_STATUS Status;
@@ -737,8 +753,8 @@ MnpWrapRxData (
&RxDataWrap->RxData.RecycleEvent
);
if (EFI_ERROR (Status)) {
-
DEBUG ((EFI_D_ERROR, "MnpDispatchPacket: gBS->CreateEvent failed, %r.\n", Status));
+
FreePool (RxDataWrap);
return NULL;
}
@@ -758,8 +774,8 @@ MnpWrapRxData (
**/
VOID
MnpEnqueuePacket (
- IN MNP_SERVICE_DATA *MnpServiceData,
- IN NET_BUF *Nbuf
+ IN MNP_SERVICE_DATA *MnpServiceData,
+ IN NET_BUF *Nbuf
)
{
LIST_ENTRY *Entry;
@@ -776,7 +792,7 @@ MnpEnqueuePacket (
//
MnpAnalysePacket (MnpServiceData, Nbuf, &RxData, &GroupAddress, &PktAttr);
- if (RxData.PromiscuousFlag && (MnpServiceData->PromiscuousCount == 0)) {
+ if (RxData.PromiscuousFlag && (MnpServiceData->MnpDeviceData->PromiscuousCount == 0)) {
//
// No receivers, no more action need.
//
@@ -799,7 +815,6 @@ MnpEnqueuePacket (
// Check the packet against the instance receive filters.
//
if (MnpMatchPacket (Instance, &RxData, GroupAddress, PktAttr)) {
-
//
// Wrap the RxData.
//
@@ -826,7 +841,7 @@ MnpEnqueuePacket (
/**
Try to receive a packet and deliver it.
- @param[in, out] MnpServiceData Pointer to the mnp service context data.
+ @param[in, out] MnpDeviceData Pointer to the mnp device context data.
@retval EFI_SUCCESS add return value to function comment
@retval EFI_NOT_STARTED The simple network protocol is not started.
@@ -836,7 +851,7 @@ MnpEnqueuePacket (
**/
EFI_STATUS
MnpReceivePacket (
- IN OUT MNP_SERVICE_DATA *MnpServiceData
+ IN OUT MNP_DEVICE_DATA *MnpDeviceData
)
{
EFI_STATUS Status;
@@ -846,10 +861,13 @@ MnpReceivePacket (
UINTN BufLen;
UINTN HeaderSize;
UINT32 Trimmed;
+ MNP_SERVICE_DATA *MnpServiceData;
+ UINT16 VlanId;
+ BOOLEAN IsVlanPacket;
- NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
+ NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
- Snp = MnpServiceData->Snp;
+ Snp = MnpDeviceData->Snp;
if (Snp->Mode->State != EfiSimpleNetworkInitialized) {
//
// The simple network protocol is not started.
@@ -857,20 +875,13 @@ MnpReceivePacket (
return EFI_NOT_STARTED;
}
- if (IsListEmpty (&MnpServiceData->ChildrenList)) {
- //
- // There is no child, no need to receive packets.
- //
- return EFI_SUCCESS;
- }
-
- if (MnpServiceData->RxNbufCache == NULL) {
+ if (MnpDeviceData->RxNbufCache == NULL) {
//
// Try to get a new buffer as there may be buffers recycled.
//
- MnpServiceData->RxNbufCache = MnpAllocNbuf (MnpServiceData);
+ MnpDeviceData->RxNbufCache = MnpAllocNbuf (MnpDeviceData);
- if (MnpServiceData->RxNbufCache == NULL) {
+ if (MnpDeviceData->RxNbufCache == NULL) {
//
// No availabe buffer in the buffer pool.
//
@@ -878,13 +889,13 @@ MnpReceivePacket (
}
NetbufAllocSpace (
- MnpServiceData->RxNbufCache,
- MnpServiceData->BufferLength,
+ MnpDeviceData->RxNbufCache,
+ MnpDeviceData->BufferLength,
NET_BUF_TAIL
);
}
- Nbuf = MnpServiceData->RxNbufCache;
+ Nbuf = MnpDeviceData->RxNbufCache;
BufLen = Nbuf->TotalSize;
BufPtr = NetbufGetByte (Nbuf, 0, NULL);
ASSERT (BufPtr != NULL);
@@ -894,7 +905,6 @@ MnpReceivePacket (
//
Status = Snp->Receive (Snp, &HeaderSize, &BufLen, BufPtr, NULL, NULL, NULL);
if (EFI_ERROR (Status)) {
-
DEBUG_CODE (
if (Status != EFI_NOT_READY) {
DEBUG ((EFI_D_WARN, "MnpReceivePacket: Snp->Receive() = %r.\n", Status));
@@ -908,7 +918,6 @@ MnpReceivePacket (
// Sanity check.
//
if ((HeaderSize != Snp->Mode->MediaHeaderSize) || (BufLen < HeaderSize)) {
-
DEBUG (
(EFI_D_WARN,
"MnpReceivePacket: Size error, HL:TL = %d:%d.\n",
@@ -927,6 +936,32 @@ MnpReceivePacket (
ASSERT (Nbuf->TotalSize == BufLen);
}
+ VlanId = 0;
+ 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) {
+ //
+ // VLAN is not set for this tagged frame, ignore this packet
+ //
+ if (Trimmed > 0) {
+ NetbufAllocSpace (Nbuf, Trimmed, NET_BUF_TAIL);
+ }
+
+ if (IsVlanPacket) {
+ NetbufAllocSpace (Nbuf, NET_VLAN_TAG_LEN, NET_BUF_HEAD);
+ }
+
+ goto EXIT;
+ }
+
//
// Enqueue the packet to the matched instances.
//
@@ -937,16 +972,16 @@ MnpReceivePacket (
// RefCnt > 2 indicates there is at least one receiver of this packet.
// Free the current RxNbufCache and allocate a new one.
//
- MnpFreeNbuf (MnpServiceData, Nbuf);
+ MnpFreeNbuf (MnpDeviceData, Nbuf);
- Nbuf = MnpAllocNbuf (MnpServiceData);
- MnpServiceData->RxNbufCache = Nbuf;
+ Nbuf = MnpAllocNbuf (MnpDeviceData);
+ MnpDeviceData->RxNbufCache = Nbuf;
if (Nbuf == NULL) {
DEBUG ((EFI_D_ERROR, "MnpReceivePacket: Alloc packet for receiving cache failed.\n"));
return EFI_DEVICE_ERROR;
}
- NetbufAllocSpace (Nbuf, MnpServiceData->BufferLength, NET_BUF_TAIL);
+ NetbufAllocSpace (Nbuf, MnpDeviceData->BufferLength, NET_BUF_TAIL);
} else {
//
// No receiver for this packet.
@@ -954,6 +989,9 @@ MnpReceivePacket (
if (Trimmed > 0) {
NetbufAllocSpace (Nbuf, Trimmed, NET_BUF_TAIL);
}
+ if (IsVlanPacket) {
+ NetbufAllocSpace (Nbuf, NET_VLAN_TAG_LEN, NET_BUF_HEAD);
+ }
goto EXIT;
}
@@ -964,7 +1002,7 @@ MnpReceivePacket (
EXIT:
- ASSERT (Nbuf->TotalSize == MnpServiceData->BufferLength);
+ ASSERT (Nbuf->TotalSize == MnpDeviceData->BufferLength);
return Status;
}
@@ -973,93 +1011,127 @@ EXIT:
/**
Remove the received packets if timeout occurs.
- @param[in] Event The event this notify function registered to.
- @param[in] Context Pointer to the context data registered to the
- event.
-
+ @param[in] Event The event this notify function registered to.
+ @param[in] Context Pointer to the context data registered to the event.
+
**/
VOID
EFIAPI
MnpCheckPacketTimeout (
- IN EFI_EVENT Event,
- IN VOID *Context
+ IN EFI_EVENT Event,
+ IN VOID *Context
)
{
+ MNP_DEVICE_DATA *MnpDeviceData;
MNP_SERVICE_DATA *MnpServiceData;
LIST_ENTRY *Entry;
+ LIST_ENTRY *ServiceEntry;
LIST_ENTRY *RxEntry;
LIST_ENTRY *NextEntry;
MNP_INSTANCE_DATA *Instance;
MNP_RXDATA_WRAP *RxDataWrap;
EFI_TPL OldTpl;
- MnpServiceData = (MNP_SERVICE_DATA *) Context;
- NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
+ MnpDeviceData = (MNP_DEVICE_DATA *) Context;
+ NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
- NET_LIST_FOR_EACH (Entry, &MnpServiceData->ChildrenList) {
+ NET_LIST_FOR_EACH (ServiceEntry, &MnpDeviceData->ServiceList) {
+ MnpServiceData = MNP_SERVICE_DATA_FROM_LINK (ServiceEntry);
- Instance = NET_LIST_USER_STRUCT (Entry, MNP_INSTANCE_DATA, InstEntry);
- NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
+ NET_LIST_FOR_EACH (Entry, &MnpServiceData->ChildrenList) {
- if (!Instance->Configured || (Instance->ConfigData.ReceivedQueueTimeoutValue == 0)) {
- //
- // This instance is not configured or there is no receive time out,
- // just skip to the next instance.
- //
- continue;
- }
+ Instance = NET_LIST_USER_STRUCT (Entry, MNP_INSTANCE_DATA, InstEntry);
+ NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+ if (!Instance->Configured || (Instance->ConfigData.ReceivedQueueTimeoutValue == 0)) {
+ //
+ // This instance is not configured or there is no receive time out,
+ // just skip to the next instance.
+ //
+ continue;
+ }
- NET_LIST_FOR_EACH_SAFE (RxEntry, NextEntry, &Instance->RcvdPacketQueue) {
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
- RxDataWrap = NET_LIST_USER_STRUCT (RxEntry, MNP_RXDATA_WRAP, WrapEntry);
+ NET_LIST_FOR_EACH_SAFE (RxEntry, NextEntry, &Instance->RcvdPacketQueue) {
- //
- // TimeoutTick unit is microsecond, MNP_TIMEOUT_CHECK_INTERVAL unit is 100ns.
- //
- if (RxDataWrap->TimeoutTick >= (MNP_TIMEOUT_CHECK_INTERVAL / 10)) {
+ RxDataWrap = NET_LIST_USER_STRUCT (RxEntry, MNP_RXDATA_WRAP, WrapEntry);
- RxDataWrap->TimeoutTick -= (MNP_TIMEOUT_CHECK_INTERVAL / 10);
- } else {
//
- // Drop the timeout packet.
+ // TimeoutTick unit is microsecond, MNP_TIMEOUT_CHECK_INTERVAL unit is 100ns.
//
- DEBUG ((EFI_D_WARN, "MnpCheckPacketTimeout: Received packet timeout.\n"));
- MnpRecycleRxData (NULL, RxDataWrap);
- Instance->RcvdPacketQueueSize--;
+ if (RxDataWrap->TimeoutTick >= (MNP_TIMEOUT_CHECK_INTERVAL / 10)) {
+ RxDataWrap->TimeoutTick -= (MNP_TIMEOUT_CHECK_INTERVAL / 10);
+ } else {
+ //
+ // Drop the timeout packet.
+ //
+ DEBUG ((EFI_D_WARN, "MnpCheckPacketTimeout: Received packet timeout.\n"));
+ MnpRecycleRxData (NULL, RxDataWrap);
+ Instance->RcvdPacketQueueSize--;
+ }
}
- }
- gBS->RestoreTPL (OldTpl);
+ gBS->RestoreTPL (OldTpl);
+ }
}
}
+/**
+ Poll to update MediaPresent field in SNP ModeData by Snp->GetStatus().
+
+ @param[in] Event The event this notify function registered to.
+ @param[in] Context Pointer to the context data registered to the event.
+
+**/
+VOID
+EFIAPI
+MnpCheckMediaStatus (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ MNP_DEVICE_DATA *MnpDeviceData;
+ EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
+ UINT32 InterruptStatus;
+
+ MnpDeviceData = (MNP_DEVICE_DATA *) Context;
+ NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
+
+ Snp = MnpDeviceData->Snp;
+ if (Snp->Mode->MediaPresentSupported) {
+ //
+ // Upon successful return of GetStatus(), the MediaPresent field of
+ // EFI_SIMPLE_NETWORK_MODE will be updated to reflect any change of media status
+ //
+ Snp->GetStatus (Snp, &InterruptStatus, NULL);
+ }
+}
/**
Poll to receive the packets from Snp. This function is either called by upperlayer
protocols/applications or the system poll timer notify mechanism.
- @param[in] Event The event this notify function registered to.
- @param[in, out] Context Pointer to the context data registered to the event.
+ @param[in] Event The event this notify function registered to.
+ @param[in] Context Pointer to the context data registered to the event.
**/
VOID
EFIAPI
MnpSystemPoll (
- IN EFI_EVENT Event,
- IN OUT VOID *Context
+ IN EFI_EVENT Event,
+ IN VOID *Context
)
{
- MNP_SERVICE_DATA *MnpServiceData;
+ MNP_DEVICE_DATA *MnpDeviceData;
- MnpServiceData = (MNP_SERVICE_DATA *) Context;
- NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
+ MnpDeviceData = (MNP_DEVICE_DATA *) Context;
+ NET_CHECK_SIGNATURE (MnpDeviceData, MNP_DEVICE_DATA_SIGNATURE);
//
// Try to receive packets from Snp.
//
- MnpReceivePacket (MnpServiceData);
+ MnpReceivePacket (MnpDeviceData);
//
// Dispatch the DPC queued by the NotifyFunction of rx token's events.