X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FNetwork%2FMnpDxe%2FMnpIo.c;h=b8f61bf696fe1d82e45b9122202e18ee59da1d67;hp=ed8bf78282d6d5f0ae49cdc2dcb5999aa5dd849a;hb=bdebd2cecf015a5feb11e99269731cac606167e8;hpb=36ee91ca3661d3d020a7841aacbf858d885c4728 diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpIo.c index ed8bf78282..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 -#include -#include -#include #include "MnpImpl.h" - +#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,14 +40,14 @@ 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)) { // // The token is invalid if the Event is NULL, or the TxData is NULL, or // the fragment count is zero. // - MNP_DEBUG_WARN (("MnpIsValidTxToken: Invalid Token.\n")); + DEBUG ((EFI_D_WARN, "MnpIsValidTxToken: Invalid Token.\n")); return FALSE; } @@ -67,7 +56,7 @@ MnpIsValidTxToken ( // The token is invalid if the HeaderLength isn't zero while the DestinationAddress // is NULL (The destination address is already put into the packet). // - MNP_DEBUG_WARN (("MnpIsValidTxToken: DestinationAddress isn't NULL, HeaderLength must be 0.\n")); + DEBUG ((EFI_D_WARN, "MnpIsValidTxToken: DestinationAddress isn't NULL, HeaderLength must be 0.\n")); return FALSE; } @@ -79,7 +68,7 @@ MnpIsValidTxToken ( // // The token is invalid if any FragmentLength is zero or any FragmentBuffer is NULL. // - MNP_DEBUG_WARN (("MnpIsValidTxToken: Invalid FragmentLength or FragmentBuffer.\n")); + DEBUG ((EFI_D_WARN, "MnpIsValidTxToken: Invalid FragmentLength or FragmentBuffer.\n")); return FALSE; } @@ -98,7 +87,7 @@ MnpIsValidTxToken ( // The length calculated from the fragment information doesn't equal to the // sum of the DataLength and the HeaderLength. // - MNP_DEBUG_WARN (("MnpIsValidTxData: Invalid Datalength compared with the sum of fragment length.\n")); + DEBUG ((EFI_D_WARN, "MnpIsValidTxData: Invalid Datalength compared with the sum of fragment length.\n")); return FALSE; } @@ -106,7 +95,7 @@ MnpIsValidTxToken ( // // The total length is larger than the MTU. // - MNP_DEBUG_WARN (("MnpIsValidTxData: TxData->DataLength exceeds Mtu.\n")); + DEBUG ((EFI_D_WARN, "MnpIsValidTxData: TxData->DataLength exceeds Mtu.\n")); return FALSE; } @@ -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) { @@ -169,7 +168,7 @@ MnpBuildTxPacket ( // // Copy the data. // - NetCopyMem ( + CopyMem ( DstPos, TxData->FragmentTable[Index].FragmentBuffer, TxData->FragmentTable[Index].FragmentLength @@ -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,20 +337,20 @@ 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) || NetListIsEmpty (&Instance->RcvdPacketQueue)) { + if (NetMapIsEmpty (&Instance->RxTokenMap) || IsListEmpty (&Instance->RcvdPacketQueue)) { // // No pending received data or no available receive token, return. // @@ -344,9 +365,9 @@ 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) { - MNP_DEBUG_WARN (("MnpDeliverPacket: Failed to allocate a free Nbuf.\n")); + DEBUG ((EFI_D_WARN, "MnpDeliverPacket: Failed to allocate a free Nbuf.\n")); return EFI_OUT_OF_RESOURCES; } @@ -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. @@ -379,7 +400,7 @@ MnpInstanceDeliverPacket ( // // Insert this RxDataWrap into the delivered queue. // - NetListInsertTail (&Instance->RxDeliveredPacketQueue, &RxDataWrap->WrapEntry); + InsertTailList (&Instance->RxDeliveredPacketQueue, &RxDataWrap->WrapEntry); // // Get the receive token from the RxTokenMap. @@ -400,18 +421,15 @@ 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. **/ -STATIC VOID MnpDeliverPacket ( - IN MNP_SERVICE_DATA *MnpServiceData + IN MNP_SERVICE_DATA *MnpServiceData ) { - NET_LIST_ENTRY *Entry; + LIST_ENTRY *Entry; MNP_INSTANCE_DATA *Instance; NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE); @@ -432,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); @@ -455,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; // @@ -472,27 +488,23 @@ MnpRecycleRxData ( // // Remove this Wrap entry from the list. // - NetListRemoveEntry (&RxDataWrap->WrapEntry); + RemoveEntryList (&RxDataWrap->WrapEntry); - NetFreePool (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. **/ -STATIC 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; @@ -505,7 +517,7 @@ MnpQueueRcvdPacket ( // if (Instance->RcvdPacketQueueSize == MNP_MAX_RCVD_PACKET_QUE_SIZE) { - MNP_DEBUG_WARN (("MnpQueueRcvdPacket: Drop one packet bcz queue size limit reached.\n")); + DEBUG ((EFI_D_WARN, "MnpQueueRcvdPacket: Drop one packet bcz queue size limit reached.\n")); // // Get the oldest packet. @@ -531,7 +543,7 @@ MnpQueueRcvdPacket ( // // Insert this Wrap into the instance queue. // - NetListInsertTail (&Instance->RcvdPacketQueue, &RxDataWrap->WrapEntry); + InsertTailList (&Instance->RcvdPacketQueue, &RxDataWrap->WrapEntry); Instance->RcvdPacketQueueSize++; } @@ -539,28 +551,27 @@ 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. **/ -STATIC 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; - NET_LIST_ENTRY *Entry; + LIST_ENTRY *Entry; MNP_GROUP_CONTROL_BLOCK *GroupCtrlBlk; NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE); @@ -618,35 +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. **/ -STATIC 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; - NET_LIST_ENTRY *Entry; + LIST_ENTRY *Entry; - SnpMode = MnpServiceData->Snp->Mode; + MnpDeviceData = MnpServiceData->MnpDeviceData; + SnpMode = MnpDeviceData->Snp->Mode; // // Get the packet buffer. @@ -678,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)) { @@ -695,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. // @@ -707,7 +717,7 @@ MnpAnalysePacket ( } } - NetZeroMem (&RxData->Timestamp, sizeof (EFI_TIME)); + ZeroMem (&RxData->Timestamp, sizeof (EFI_TIME)); // // Fill the common parts of RxData. @@ -723,17 +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. **/ -STATIC 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; @@ -742,9 +751,9 @@ MnpWrapRxData ( // // Allocate memory. // - RxDataWrap = NetAllocatePool (sizeof (MNP_RXDATA_WRAP)); + RxDataWrap = AllocatePool (sizeof (MNP_RXDATA_WRAP)); if (RxDataWrap == NULL) { - MNP_DEBUG_ERROR (("MnpDispatchPacket: Failed to allocate a MNP_RXDATA_WRAP.\n")); + DEBUG ((EFI_D_ERROR, "MnpDispatchPacket: Failed to allocate a MNP_RXDATA_WRAP.\n")); return NULL; } @@ -760,15 +769,15 @@ MnpWrapRxData ( // Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL, - NET_TPL_RECYCLE, + TPL_NOTIFY, MnpRecycleRxData, RxDataWrap, &RxDataWrap->RxData.RecycleEvent ); if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "MnpDispatchPacket: gBS->CreateEvent failed, %r.\n", Status)); - MNP_DEBUG_ERROR (("MnpDispatchPacket: gBS->CreateEvent failed, %r.\n", Status)); - NetFreePool (RxDataWrap); + FreePool (RxDataWrap); return NULL; } @@ -780,21 +789,18 @@ 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. - **/ -STATIC VOID MnpEnqueuePacket ( - IN MNP_SERVICE_DATA *MnpServiceData, - IN NET_BUF *Nbuf + IN MNP_SERVICE_DATA *MnpServiceData, + IN NET_BUF *Nbuf ) { - NET_LIST_ENTRY *Entry; + LIST_ENTRY *Entry; MNP_INSTANCE_DATA *Instance; EFI_MANAGED_NETWORK_RECEIVE_DATA RxData; UINT8 PktAttr; @@ -808,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. // @@ -831,7 +837,6 @@ MnpEnqueuePacket ( // Check the packet against the instance receive filters. // if (MnpMatchPacket (Instance, &RxData, GroupAddress, PktAttr)) { - // // Wrap the RxData. // @@ -858,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. @@ -868,7 +873,7 @@ MnpEnqueuePacket ( **/ EFI_STATUS MnpReceivePacket ( - IN MNP_SERVICE_DATA *MnpServiceData + IN OUT MNP_DEVICE_DATA *MnpDeviceData ) { EFI_STATUS Status; @@ -878,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. @@ -889,20 +897,13 @@ MnpReceivePacket ( return EFI_NOT_STARTED; } - if (NetListIsEmpty (&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. // @@ -910,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); @@ -926,11 +927,10 @@ MnpReceivePacket ( // Status = Snp->Receive (Snp, &HeaderSize, &BufLen, BufPtr, NULL, NULL, NULL); if (EFI_ERROR (Status)) { - DEBUG_CODE ( if (Status != EFI_NOT_READY) { - MNP_DEBUG_ERROR (("MnpReceivePacket: Snp->Receive() = %r.\n", Status)); - } + DEBUG ((EFI_D_WARN, "MnpReceivePacket: Snp->Receive() = %r.\n", Status)); + } ); return Status; @@ -940,9 +940,9 @@ MnpReceivePacket ( // Sanity check. // if ((HeaderSize != Snp->Mode->MediaHeaderSize) || (BufLen < HeaderSize)) { - - MNP_DEBUG_WARN ( - ("MnpReceivePacket: Size error, HL:TL = %d:%d.\n", + DEBUG ( + (EFI_D_WARN, + "MnpReceivePacket: Size error, HL:TL = %d:%d.\n", HeaderSize, BufLen) ); @@ -958,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. // @@ -968,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) { - MNP_DEBUG_ERROR (("MnpReceivePacket: Alloc packet for receiving cache failed.\n")); + 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. @@ -985,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; } @@ -993,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; } @@ -1009,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; - NET_LIST_ENTRY *Entry; - NET_LIST_ENTRY *RxEntry; - NET_LIST_ENTRY *NextEntry; + 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 = NET_RAISE_TPL (NET_TPL_RECYCLE); + 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. // - MNP_DEBUG_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--; + } } - } - NET_RESTORE_TPL (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 (); }