X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FNetwork%2FMnpDxe%2FMnpIo.c;h=b8f61bf696fe1d82e45b9122202e18ee59da1d67;hp=0c8196a7689efefd13a9f8b3f8a1c835020185f2;hb=bdebd2cecf015a5feb11e99269731cac606167e8;hpb=d8d26fb207e02aa5ef57e2bcb213f9dda16166cc diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c index 0c8196a768..b8f61bf696 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 - 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, @@ -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)) { // @@ -105,31 +107,43 @@ MnpIsValidTxToken ( 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. **/ 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 { // @@ -137,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) { @@ -165,7 +179,7 @@ MnpBuildTxPacket ( // // Set the buffer pointer and the buffer length. // - *PktBuf = MnpServiceData->TxBuf; + *PktBuf = MnpDerviceData->TxBuf; *PktLen += TxData->DataLength + TxData->HeaderLength; } } @@ -186,10 +200,10 @@ 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; @@ -197,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. @@ -227,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; } @@ -247,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 ); @@ -272,7 +308,7 @@ MnpSyncSendPacket ( // // Cancel the timer event. // - gBS->SetTimer (MnpServiceData->TxTimeoutEvent, TimerCancel, 0); + gBS->SetTimer (MnpDeviceData->TxTimeoutEvent, TimerCancel, 0); SIGNAL_TOKEN: @@ -301,18 +337,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 +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")); @@ -340,7 +376,7 @@ MnpInstanceDeliverPacket ( // Duplicate the net buffer. // NetbufDuplicate (RxDataWrap->Nbuf, DupNbuf, 0); - MnpFreeNbuf (MnpServiceData, RxDataWrap->Nbuf); + MnpFreeNbuf (MnpDeviceData, RxDataWrap->Nbuf); RxDataWrap->Nbuf = DupNbuf; } @@ -351,7 +387,7 @@ MnpInstanceDeliverPacket ( Instance->RcvdPacketQueueSize--; RxData = &RxDataWrap->RxData; - SnpMode = MnpServiceData->Snp->Mode; + SnpMode = MnpDeviceData->Snp->Mode; // // Set all the buffer pointers. @@ -390,7 +426,7 @@ MnpInstanceDeliverPacket ( **/ VOID MnpDeliverPacket ( - IN MNP_SERVICE_DATA *MnpServiceData + IN MNP_SERVICE_DATA *MnpServiceData ) { LIST_ENTRY *Entry; @@ -421,12 +457,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 +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; // @@ -454,7 +490,7 @@ MnpRecycleRxData ( // RemoveEntryList (&RxDataWrap->WrapEntry); - gBS->FreePool (RxDataWrap); + FreePool (RxDataWrap); } @@ -467,8 +503,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 +564,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 +643,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 +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)) { @@ -667,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. // @@ -703,8 +741,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,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; } @@ -758,8 +796,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 +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. // @@ -799,7 +837,6 @@ MnpEnqueuePacket ( // Check the packet against the instance receive filters. // if (MnpMatchPacket (Instance, &RxData, GroupAddress, PktAttr)) { - // // Wrap the RxData. // @@ -826,7 +863,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 +873,7 @@ MnpEnqueuePacket ( **/ EFI_STATUS MnpReceivePacket ( - IN OUT MNP_SERVICE_DATA *MnpServiceData + IN OUT MNP_DEVICE_DATA *MnpDeviceData ) { EFI_STATUS Status; @@ -846,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. @@ -857,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. // @@ -878,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); @@ -894,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)); @@ -908,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", @@ -927,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. // @@ -937,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. @@ -954,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; } @@ -964,7 +1024,7 @@ MnpReceivePacket ( EXIT: - ASSERT (Nbuf->TotalSize == MnpServiceData->BufferLength); + ASSERT (Nbuf->TotalSize == MnpDeviceData->BufferLength); return Status; } @@ -973,93 +1033,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 ms, 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.