X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FNetwork%2FMnpDxe%2FMnpIo.c;h=b8f61bf696fe1d82e45b9122202e18ee59da1d67;hp=13bf552339a1be9f2828a763bbb5766a522df757;hb=bdebd2cecf015a5feb11e99269731cac606167e8;hpb=fe1e36e550c6ffcd2561903d434683d3939e1942
diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c
index 13bf552339..b8f61bf696 100644
--- a/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c
+++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c
@@ -1,45 +1,34 @@
/** @file
+ Implementation of Managed Network Protocol I/O functions.
-Copyright (c) 2005 - 2007, 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 - 2013, 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.
-Module Name:
-
- MnpIo.c
-
-Abstract:
-
- Implementation of Managed Network Protocol I/O functions.
-
-
**/
#include "MnpImpl.h"
-#include
-#include
-#include
-#include
-
+#include "MnpVlan.h"
/**
Validates the Mnp transmit token.
- @param Instance Pointer to the Mnp instance context data.
- @param Token Pointer to the transmit token to check.
+ @param[in] Instance Pointer to the Mnp instance context data.
+ @param[in] Token Pointer to the transmit token to check.
@return The Token is valid or not.
**/
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;
@@ -51,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)) {
//
@@ -117,34 +106,44 @@ MnpIsValidTxToken (
/**
Build the packet to transmit from the TxData passed in.
- @param MnpServiceData Pointer to the mnp service context data.
- @param TxData Pointer to the transmit data containing the
- information to build the packet.
- @param PktBuf Pointer to record the address of the packet.
- @param PktLen Pointer to a UINT32 variable used to record the
- packet's length.
-
- @return None.
+ @param[in] MnpServiceData Pointer to the mnp service context data.
+ @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
+ length.
**/
VOID
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 *MnpDerviceData;
+ 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.
+ // Reserve space for vlan tag,if necessary.
//
- *PktBuf = TxData->FragmentTable[0].FragmentBuffer;
+ if (MnpServiceData->VlanId != 0) {
+ *PktBuf = MnpDerviceData->TxBuf + NET_VLAN_TAG_LEN;
+ } else {
+ *PktBuf = MnpDerviceData->TxBuf;
+ }
+
+ CopyMem (
+ *PktBuf,
+ TxData->FragmentTable[0].FragmentBuffer,
+ TxData->FragmentTable[0].FragmentLength
+ );
+
*PktLen = TxData->FragmentTable[0].FragmentLength;
} else {
//
@@ -152,8 +151,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 = MnpDerviceData->Snp->Mode;
+ DstPos = MnpDerviceData->TxBuf;
*PktLen = 0;
if (TxData->DestinationAddress != NULL) {
@@ -180,7 +179,7 @@ MnpBuildTxPacket (
//
// Set the buffer pointer and the buffer length.
//
- *PktBuf = MnpServiceData->TxBuf;
+ *PktBuf = MnpDerviceData->TxBuf;
*PktLen += TxData->DataLength + TxData->HeaderLength;
}
}
@@ -189,22 +188,22 @@ MnpBuildTxPacket (
/**
Synchronously send out the packet.
- @param MnpServiceData Pointer to the mnp service context data.
- @param Packet Pointer to the pakcet buffer.
- @param Length The length of the packet.
- @param Token Pointer to the token the packet generated from.
+ @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.
+ @param[in, out] Token Pointer to the token the packet generated from.
- @retval EFI_SUCCESS The packet is sent out.
- @retval EFI_TIMEOUT Time out occurs, the packet isn't sent.
- @retval EFI_DEVICE_ERROR An unexpected network error occurs.
+ @retval EFI_SUCCESS The packet is sent out.
+ @retval EFI_TIMEOUT Time out occurs, the packet isn't sent.
+ @retval EFI_DEVICE_ERROR An unexpected network error occurs.
**/
EFI_STATUS
MnpSyncSendPacket (
- IN MNP_SERVICE_DATA *MnpServiceData,
- IN UINT8 *Packet,
- IN UINT32 Length,
- IN 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;
@@ -212,25 +211,50 @@ MnpSyncSendPacket (
EFI_MANAGED_NETWORK_TRANSMIT_DATA *TxData;
UINT32 HeaderSize;
UINT8 *TxBuf;
+ MNP_DEVICE_DATA *MnpDeviceData;
+ UINT16 ProtocolType;
- Snp = MnpServiceData->Snp;
- TxData = Token->Packet.TxData;
+ MnpDeviceData = MnpServiceData->MnpDeviceData;
+ Snp = MnpDeviceData->Snp;
+ TxData = Token->Packet.TxData;
- HeaderSize = Snp->Mode->MediaHeaderSize - TxData->HeaderLength;
+ HeaderSize = Snp->Mode->MediaHeaderSize - TxData->HeaderLength;
+
+ //
+ // Check media status before transmit packet.
+ // Note: media status will be updated by periodic timer MediaDetectTimer.
+ //
+ 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"));
+ Status = EFI_NO_MEDIA;
+ goto SIGNAL_TOKEN;
+ }
//
// Start the timeout event.
//
Status = gBS->SetTimer (
- MnpServiceData->TxTimeoutEvent,
+ 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;
+ }
+
for (;;) {
//
// Transmit the packet through SNP.
@@ -242,10 +266,9 @@ MnpSyncSendPacket (
Packet,
TxData->SourceAddress,
TxData->DestinationAddress,
- &TxData->ProtocolType
+ &ProtocolType
);
if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_READY)) {
-
Status = EFI_DEVICE_ERROR;
break;
}
@@ -262,22 +285,20 @@ MnpSyncSendPacket (
//
Snp->GetStatus (Snp, NULL, (VOID **) &TxBuf);
- if (!EFI_ERROR (gBS->CheckEvent (MnpServiceData->TxTimeoutEvent))) {
-
+ 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 (
- MnpServiceData->TxTimeoutEvent,
+ MnpDeviceData->TxTimeoutEvent,
TimerRelative,
MNP_TX_TIMEOUT_TIME
);
@@ -287,7 +308,7 @@ MnpSyncSendPacket (
//
// Cancel the timer event.
//
- gBS->SetTimer (MnpServiceData->TxTimeoutEvent, TimerCancel, 0);
+ gBS->SetTimer (MnpDeviceData->TxTimeoutEvent, TimerCancel, 0);
SIGNAL_TOKEN:
@@ -297,7 +318,7 @@ SIGNAL_TOKEN:
//
// Dispatch the DPC queued by the NotifyFunction of Token->Event.
//
- NetLibDispatchDpc ();
+ DispatchDpc ();
return EFI_SUCCESS;
}
@@ -306,7 +327,7 @@ SIGNAL_TOKEN:
/**
Try to deliver the received packet to the instance.
- @param Instance Pointer to the mnp instance context data.
+ @param[in, out] Instance Pointer to the mnp instance context data.
@retval EFI_SUCCESS The received packet is delivered, or there is no
packet to deliver, or there is no available receive
@@ -316,18 +337,18 @@ SIGNAL_TOKEN:
**/
EFI_STATUS
MnpInstanceDeliverPacket (
- IN 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)) {
//
@@ -344,7 +365,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"));
@@ -355,7 +376,7 @@ MnpInstanceDeliverPacket (
// Duplicate the net buffer.
//
NetbufDuplicate (RxDataWrap->Nbuf, DupNbuf, 0);
- MnpFreeNbuf (MnpServiceData, RxDataWrap->Nbuf);
+ MnpFreeNbuf (MnpDeviceData, RxDataWrap->Nbuf);
RxDataWrap->Nbuf = DupNbuf;
}
@@ -366,7 +387,7 @@ MnpInstanceDeliverPacket (
Instance->RcvdPacketQueueSize--;
RxData = &RxDataWrap->RxData;
- SnpMode = MnpServiceData->Snp->Mode;
+ SnpMode = MnpDeviceData->Snp->Mode;
//
// Set all the buffer pointers.
@@ -400,14 +421,12 @@ MnpInstanceDeliverPacket (
/**
Deliver the received packet for the instances belonging to the MnpServiceData.
- @param MnpServiceData Pointer to the mnp service context data.
-
- @return None.
+ @param[in] MnpServiceData Pointer to the mnp service context data.
**/
VOID
MnpDeliverPacket (
- IN MNP_SERVICE_DATA *MnpServiceData
+ IN MNP_SERVICE_DATA *MnpServiceData
)
{
LIST_ENTRY *Entry;
@@ -431,21 +450,19 @@ MnpDeliverPacket (
Recycle the RxData and other resources used to hold and deliver the received
packet.
- @param Event The event this notify function registered to.
- @param Context Pointer to the context data registerd to the Event.
-
- @return None.
+ @param[in] Event The event this notify function registered to.
+ @param[in] Context Pointer to the context data registerd to the Event.
**/
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);
@@ -454,13 +471,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;
//
@@ -473,24 +490,21 @@ MnpRecycleRxData (
//
RemoveEntryList (&RxDataWrap->WrapEntry);
- gBS->FreePool (RxDataWrap);
+ FreePool (RxDataWrap);
}
/**
Queue the received packet into instance's receive queue.
- @param Instance Pointer to the mnp instance context data.
- @param RxDataWrap Pointer to the Wrap structure containing the
- received data and other information.
-
- @return None.
-
+ @param[in, out] Instance Pointer to the mnp instance context data.
+ @param[in, out] RxDataWrap Pointer to the Wrap structure containing the
+ received data and other information.
**/
VOID
MnpQueueRcvdPacket (
- IN MNP_INSTANCE_DATA *Instance,
- IN MNP_RXDATA_WRAP *RxDataWrap
+ IN OUT MNP_INSTANCE_DATA *Instance,
+ IN OUT MNP_RXDATA_WRAP *RxDataWrap
)
{
MNP_RXDATA_WRAP *OldRxDataWrap;
@@ -537,23 +551,23 @@ MnpQueueRcvdPacket (
/**
Match the received packet with the instance receive filters.
- @param Instance Pointer to the mnp instance context data.
- @param RxData Pointer to the EFI_MANAGED_NETWORK_RECEIVE_DATA.
- @param GroupAddress Pointer to the GroupAddress, the GroupAddress is
+ @param[in] Instance Pointer to the mnp instance context data.
+ @param[in] RxData Pointer to the EFI_MANAGED_NETWORK_RECEIVE_DATA.
+ @param[in] GroupAddress Pointer to the GroupAddress, the GroupAddress is
non-NULL and it contains the destination multicast
mac address of the received packet if the packet
destinated to a multicast mac address.
- @param PktAttr The received packets attribute.
+ @param[in] PktAttr The received packets attribute.
@return The received packet matches the instance's receive filters or not.
**/
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;
@@ -615,34 +629,34 @@ MnpMatchPacket (
/**
Analyse the received packets.
- @param MnpServiceData Pointer to the mnp service context data.
- @param Nbuf Pointer to the net buffer holding the received
- packet.
- @param RxData Pointer to the buffer used to save the analysed
- result in EFI_MANAGED_NETWORK_RECEIVE_DATA.
- @param GroupAddress Pointer to pointer to a MNP_GROUP_ADDRESS used to
- pass out the address of the multicast address the
- received packet destinated to.
- @param PktAttr Pointer to the buffer used to save the analysed
- packet attribute.
-
- @return None.
+ @param[in] MnpServiceData Pointer to the mnp service context data.
+ @param[in] Nbuf Pointer to the net buffer holding the received
+ packet.
+ @param[in, out] RxData Pointer to the buffer used to save the analysed
+ result in EFI_MANAGED_NETWORK_RECEIVE_DATA.
+ @param[out] GroupAddress Pointer to pointer to a MNP_GROUP_ADDRESS used to
+ pass out the address of the multicast address the
+ received packet destinated to.
+ @param[out] PktAttr Pointer to the buffer used to save the analysed
+ packet attribute.
**/
VOID
MnpAnalysePacket (
- IN MNP_SERVICE_DATA *MnpServiceData,
- IN NET_BUF *Nbuf,
- IN 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.
@@ -674,7 +688,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)) {
@@ -691,7 +705,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.
//
@@ -719,16 +733,16 @@ MnpAnalysePacket (
/**
Wrap the RxData.
- @param Instance Pointer to the mnp instance context data.
- @param RxData Pointer to the receive data to wrap.
+ @param[in] Instance Pointer to the mnp instance context data.
+ @param[in] RxData Pointer to the receive data to wrap.
@return Pointer to a MNP_RXDATA_WRAP which wraps the RxData.
**/
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;
@@ -761,9 +775,9 @@ MnpWrapRxData (
&RxDataWrap->RxData.RecycleEvent
);
if (EFI_ERROR (Status)) {
-
DEBUG ((EFI_D_ERROR, "MnpDispatchPacket: gBS->CreateEvent failed, %r.\n", Status));
- gBS->FreePool (RxDataWrap);
+
+ FreePool (RxDataWrap);
return NULL;
}
@@ -775,17 +789,15 @@ MnpWrapRxData (
Enqueue the received the packets to the instances belonging to the
MnpServiceData.
- @param MnpServiceData Pointer to the mnp service context data.
- @param Nbuf Pointer to the net buffer representing the received
+ @param[in] MnpServiceData Pointer to the mnp service context data.
+ @param[in] Nbuf Pointer to the net buffer representing the received
packet.
- @return None.
-
**/
VOID
MnpEnqueuePacket (
- IN MNP_SERVICE_DATA *MnpServiceData,
- IN NET_BUF *Nbuf
+ IN MNP_SERVICE_DATA *MnpServiceData,
+ IN NET_BUF *Nbuf
)
{
LIST_ENTRY *Entry;
@@ -802,7 +814,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.
//
@@ -825,7 +837,6 @@ MnpEnqueuePacket (
// Check the packet against the instance receive filters.
//
if (MnpMatchPacket (Instance, &RxData, GroupAddress, PktAttr)) {
-
//
// Wrap the RxData.
//
@@ -852,7 +863,7 @@ MnpEnqueuePacket (
/**
Try to receive a packet and deliver it.
- @param 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.
@@ -862,7 +873,7 @@ MnpEnqueuePacket (
**/
EFI_STATUS
MnpReceivePacket (
- IN MNP_SERVICE_DATA *MnpServiceData
+ IN OUT MNP_DEVICE_DATA *MnpDeviceData
)
{
EFI_STATUS Status;
@@ -872,10 +883,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.
@@ -883,20 +897,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.
//
@@ -904,13 +911,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);
@@ -920,7 +927,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));
@@ -934,7 +940,6 @@ MnpReceivePacket (
// Sanity check.
//
if ((HeaderSize != Snp->Mode->MediaHeaderSize) || (BufLen < HeaderSize)) {
-
DEBUG (
(EFI_D_WARN,
"MnpReceivePacket: Size error, HL:TL = %d:%d.\n",
@@ -953,6 +958,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.
//
@@ -963,16 +994,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.
@@ -980,6 +1011,9 @@ MnpReceivePacket (
if (Trimmed > 0) {
NetbufAllocSpace (Nbuf, Trimmed, NET_BUF_TAIL);
}
+ if (IsVlanPacket) {
+ NetbufAllocSpace (Nbuf, NET_VLAN_TAG_LEN, NET_BUF_HEAD);
+ }
goto EXIT;
}
@@ -988,14 +1022,9 @@ MnpReceivePacket (
//
MnpDeliverPacket (MnpServiceData);
- //
- // Dispatch the DPC queued by the NotifyFunction of rx token's events.
- //
- NetLibDispatchDpc ();
-
EXIT:
- ASSERT (Nbuf->TotalSize == MnpServiceData->BufferLength);
+ ASSERT (Nbuf->TotalSize == MnpDeviceData->BufferLength);
return Status;
}
@@ -1004,95 +1033,130 @@ EXIT:
/**
Remove the received packets if timeout occurs.
- @param Event The event this notify function registered to.
- @param Context Pointer to the context data registered to the
- event.
-
- @return None.
+ @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) {
- if (RxDataWrap->TimeoutTick >= MNP_TIMEOUT_CHECK_INTERVAL) {
+ RxDataWrap = NET_LIST_USER_STRUCT (RxEntry, MNP_RXDATA_WRAP, WrapEntry);
- RxDataWrap->TimeoutTick -= MNP_TIMEOUT_CHECK_INTERVAL;
- } 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 Event The event this notify function registered to.
- @param Context Pointer to the context data registered to the
- event.
-
- @return None.
+ @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 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);
- NetLibDispatchDpc ();
+ //
+ // Dispatch the DPC queued by the NotifyFunction of rx token's events.
+ //
+ DispatchDpc ();
}