diff options
Diffstat (limited to 'roms/edk2/NetworkPkg/MnpDxe/MnpMain.c')
-rw-r--r-- | roms/edk2/NetworkPkg/MnpDxe/MnpMain.c | 789 |
1 files changed, 789 insertions, 0 deletions
diff --git a/roms/edk2/NetworkPkg/MnpDxe/MnpMain.c b/roms/edk2/NetworkPkg/MnpDxe/MnpMain.c new file mode 100644 index 000000000..ff7e89de1 --- /dev/null +++ b/roms/edk2/NetworkPkg/MnpDxe/MnpMain.c @@ -0,0 +1,789 @@ +/** @file
+ Implementation of Managed Network Protocol public services.
+
+Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MnpImpl.h"
+
+/**
+ Returns the operational parameters for the current MNP child driver. May also
+ support returning the underlying SNP driver mode data.
+
+ The GetModeData() function is used to read the current mode data (operational
+ parameters) from the MNP or the underlying SNP.
+
+ @param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
+ @param[out] MnpConfigData Pointer to storage for MNP operational parameters. Type
+ EFI_MANAGED_NETWORK_CONFIG_DATA is defined in "Related
+ Definitions" below.
+ @param[out] SnpModeData Pointer to storage for SNP operational parameters. This
+ feature may be unsupported. Type EFI_SIMPLE_NETWORK_MODE
+ is defined in the EFI_SIMPLE_NETWORK_PROTOCOL.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER This is NULL.
+ @retval EFI_UNSUPPORTED The requested feature is unsupported in this
+ MNP implementation.
+ @retval EFI_NOT_STARTED This MNP child driver instance has not been
+ configured. The default values are returned in
+ MnpConfigData if it is not NULL.
+ @retval Others The mode data could not be read.
+
+**/
+EFI_STATUS
+EFIAPI
+MnpGetModeData (
+ IN EFI_MANAGED_NETWORK_PROTOCOL *This,
+ OUT EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL,
+ OUT EFI_SIMPLE_NETWORK_MODE *SnpModeData OPTIONAL
+ )
+{
+ MNP_INSTANCE_DATA *Instance;
+ EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+ UINT32 InterruptStatus;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ if (MnpConfigData != NULL) {
+ //
+ // Copy the instance configuration data.
+ //
+ CopyMem (MnpConfigData, &Instance->ConfigData, sizeof (*MnpConfigData));
+ }
+
+ if (SnpModeData != NULL) {
+ //
+ // Copy the underlayer Snp mode data.
+ //
+ Snp = Instance->MnpServiceData->MnpDeviceData->Snp;
+
+ //
+ // Upon successful return of GetStatus(), the Snp->Mode->MediaPresent
+ // will be updated to reflect any change of media status
+ //
+ Snp->GetStatus (Snp, &InterruptStatus, NULL);
+ CopyMem (SnpModeData, Snp->Mode, sizeof (*SnpModeData));
+ }
+
+ if (!Instance->Configured) {
+ Status = EFI_NOT_STARTED;
+ } else {
+ Status = EFI_SUCCESS;
+ }
+
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+
+/**
+ Sets or clears the operational parameters for the MNP child driver.
+
+ The Configure() function is used to set, change, or reset the operational
+ parameters for the MNP child driver instance. Until the operational parameters
+ have been set, no network traffic can be sent or received by this MNP child
+ driver instance. Once the operational parameters have been reset, no more
+ traffic can be sent or received until the operational parameters have been set
+ again.
+ Each MNP child driver instance can be started and stopped independently of
+ each other by setting or resetting their receive filter settings with the
+ Configure() function.
+ After any successful call to Configure(), the MNP child driver instance is
+ started. The internal periodic timer (if supported) is enabled. Data can be
+ transmitted and may be received if the receive filters have also been enabled.
+ Note: If multiple MNP child driver instances will receive the same packet
+ because of overlapping receive filter settings, then the first MNP child
+ driver instance will receive the original packet and additional instances will
+ receive copies of the original packet.
+ Note: Warning: Receive filter settings that overlap will consume extra
+ processor and/or DMA resources and degrade system and network performance.
+
+ @param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
+ @param[in] MnpConfigData Pointer to configuration data that will be assigned
+ to the MNP child driver instance. If NULL, the MNP
+ child driver instance is reset to startup defaults
+ and all pending transmit and receive requests are
+ flushed. Type EFI_MANAGED_NETWORK_CONFIG_DATA is
+ defined in EFI_MANAGED_NETWORK_PROTOCOL.GetModeData().
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is
+ TRUE:
+ * This is NULL.
+ * MnpConfigData.ProtocolTypeFilter is not
+ valid.
+ The operational data for the MNP child driver
+ instance is unchanged.
+ @retval EFI_OUT_OF_RESOURCES Required system resources (usually memory)
+ could not be allocated.
+ The MNP child driver instance has been reset to
+ startup defaults.
+ @retval EFI_UNSUPPORTED The requested feature is unsupported in
+ this [MNP] implementation. The operational data
+ for the MNP child driver instance is unchanged.
+ @retval EFI_DEVICE_ERROR An unexpected network or system error
+ occurred. The MNP child driver instance has
+ been reset to startup defaults.
+ @retval Others The MNP child driver instance has been reset to
+ startup defaults.
+
+**/
+EFI_STATUS
+EFIAPI
+MnpConfigure (
+ IN EFI_MANAGED_NETWORK_PROTOCOL *This,
+ IN EFI_MANAGED_NETWORK_CONFIG_DATA *MnpConfigData OPTIONAL
+ )
+{
+ MNP_INSTANCE_DATA *Instance;
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+
+ if ((This == NULL) ||
+ ((MnpConfigData != NULL) &&
+ (MnpConfigData->ProtocolTypeFilter > 0) &&
+ (MnpConfigData->ProtocolTypeFilter <= 1500))
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ if ((MnpConfigData == NULL) && (!Instance->Configured)) {
+ //
+ // If the instance is not configured and a reset is requested, just return.
+ //
+ Status = EFI_SUCCESS;
+ goto ON_EXIT;
+ }
+
+ //
+ // Configure the instance.
+ //
+ Status = MnpConfigureInstance (Instance, MnpConfigData);
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+
+/**
+ Translates an IP multicast address to a hardware (MAC) multicast address. This
+ function may be unsupported in some MNP implementations.
+
+ The McastIpToMac() function translates an IP multicast address to a hardware
+ (MAC) multicast address. This function may be implemented by calling the
+ underlying EFI_SIMPLE_NETWORK. MCastIpToMac() function, which may also be
+ unsupported in some MNP implementations.
+
+ @param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
+ @param[in] Ipv6Flag Set to TRUE to if IpAddress is an IPv6 multicast address.
+ Set to FALSE if IpAddress is an IPv4 multicast address.
+ @param[in] IpAddress Pointer to the multicast IP address (in network byte
+ order) to convert.
+ @param[out] MacAddress Pointer to the resulting multicast MAC address.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER One of the following conditions is TRUE:
+ * This is NULL.
+ * IpAddress is NULL.
+ * IpAddress is not a valid multicast IP
+ address.
+ * MacAddress is NULL.
+ @retval EFI_NOT_STARTED This MNP child driver instance has not been
+ configured.
+ @retval EFI_UNSUPPORTED The requested feature is unsupported in this
+ MNP implementation.
+ @retval EFI_DEVICE_ERROR An unexpected network or system error occurred.
+ @retval Others The address could not be converted.
+**/
+EFI_STATUS
+EFIAPI
+MnpMcastIpToMac (
+ IN EFI_MANAGED_NETWORK_PROTOCOL *This,
+ IN BOOLEAN Ipv6Flag,
+ IN EFI_IP_ADDRESS *IpAddress,
+ OUT EFI_MAC_ADDRESS *MacAddress
+ )
+{
+ EFI_STATUS Status;
+ MNP_INSTANCE_DATA *Instance;
+ EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
+ EFI_TPL OldTpl;
+ EFI_IPv6_ADDRESS *Ip6Address;
+
+ if ((This == NULL) || (IpAddress == NULL) || (MacAddress == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Ip6Address = &IpAddress->v6;
+
+ if ((Ipv6Flag && !IP6_IS_MULTICAST (Ip6Address)) ||
+ (!Ipv6Flag && !IP4_IS_MULTICAST (EFI_NTOHL (*IpAddress)))
+ ) {
+ //
+ // The IP address passed in is not a multicast address.
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ if (!Instance->Configured) {
+
+ Status = EFI_NOT_STARTED;
+ goto ON_EXIT;
+ }
+
+ Snp = Instance->MnpServiceData->MnpDeviceData->Snp;
+ ASSERT (Snp != NULL);
+
+ ZeroMem (MacAddress, sizeof (EFI_MAC_ADDRESS));
+
+ if (Snp->Mode->IfType == NET_IFTYPE_ETHERNET) {
+ if (!Ipv6Flag) {
+ //
+ // Translate the IPv4 address into a multicast MAC address if the NIC is an
+ // ethernet NIC according to RFC1112..
+ //
+ MacAddress->Addr[0] = 0x01;
+ MacAddress->Addr[1] = 0x00;
+ MacAddress->Addr[2] = 0x5E;
+ MacAddress->Addr[3] = (UINT8) (IpAddress->v4.Addr[1] & 0x7F);
+ MacAddress->Addr[4] = IpAddress->v4.Addr[2];
+ MacAddress->Addr[5] = IpAddress->v4.Addr[3];
+ } else {
+ //
+ // Translate the IPv6 address into a multicast MAC address if the NIC is an
+ // ethernet NIC according to RFC2464.
+ //
+
+ MacAddress->Addr[0] = 0x33;
+ MacAddress->Addr[1] = 0x33;
+ MacAddress->Addr[2] = Ip6Address->Addr[12];
+ MacAddress->Addr[3] = Ip6Address->Addr[13];
+ MacAddress->Addr[4] = Ip6Address->Addr[14];
+ MacAddress->Addr[5] = Ip6Address->Addr[15];
+ }
+
+ Status = EFI_SUCCESS;
+ } else {
+ //
+ // Invoke Snp to translate the multicast IP address.
+ //
+ Status = Snp->MCastIpToMac (
+ Snp,
+ Ipv6Flag,
+ IpAddress,
+ MacAddress
+ );
+ }
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+/**
+ Enables and disables receive filters for multicast address. This function may
+ be unsupported in some MNP implementations.
+
+ The Groups() function only adds and removes multicast MAC addresses from the
+ filter list. The MNP driver does not transmit or process Internet Group
+ Management Protocol (IGMP) packets. If JoinFlag is FALSE and MacAddress is
+ NULL, then all joined groups are left.
+
+ @param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
+ @param[in] JoinFlag Set to TRUE to join this multicast group.
+ Set to FALSE to leave this multicast group.
+ @param[in] MacAddress Pointer to the multicast MAC group (address) to join or
+ leave.
+
+ @retval EFI_SUCCESS The requested operation completed successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ * This is NULL.
+ * JoinFlag is TRUE and MacAddress is NULL.
+ * MacAddress is not a valid multicast MAC
+ address.
+ * The MNP multicast group settings are
+ unchanged.
+ @retval EFI_NOT_STARTED This MNP child driver instance has not been
+ configured.
+ @retval EFI_ALREADY_STARTED The supplied multicast group is already joined.
+ @retval EFI_NOT_FOUND The supplied multicast group is not joined.
+ @retval EFI_DEVICE_ERROR An unexpected network or system error occurred.
+ The MNP child driver instance has been reset to
+ startup defaults.
+ @retval EFI_UNSUPPORTED The requested feature is unsupported in this MNP
+ implementation.
+ @retval Others The requested operation could not be completed.
+ The MNP multicast group settings are unchanged.
+
+**/
+EFI_STATUS
+EFIAPI
+MnpGroups (
+ IN EFI_MANAGED_NETWORK_PROTOCOL *This,
+ IN BOOLEAN JoinFlag,
+ IN EFI_MAC_ADDRESS *MacAddress OPTIONAL
+ )
+{
+ MNP_INSTANCE_DATA *Instance;
+ EFI_SIMPLE_NETWORK_MODE *SnpMode;
+ MNP_GROUP_CONTROL_BLOCK *GroupCtrlBlk;
+ MNP_GROUP_ADDRESS *GroupAddress;
+ LIST_ENTRY *ListEntry;
+ BOOLEAN AddressExist;
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+
+ if (This == NULL || (JoinFlag && (MacAddress == NULL))) {
+ //
+ // This is NULL, or it's a join operation but MacAddress is NULL.
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
+ SnpMode = Instance->MnpServiceData->MnpDeviceData->Snp->Mode;
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ if (!Instance->Configured) {
+ Status = EFI_NOT_STARTED;
+ goto ON_EXIT;
+ }
+
+ if ((!Instance->ConfigData.EnableMulticastReceive) ||
+ ((MacAddress != NULL) && !NET_MAC_IS_MULTICAST (MacAddress, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize))) {
+ //
+ // The instance isn't configured to do multicast receive. OR
+ // the passed in MacAddress is not a multicast mac address.
+ //
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ Status = EFI_SUCCESS;
+ AddressExist = FALSE;
+ GroupCtrlBlk = NULL;
+
+ if (MacAddress != NULL) {
+ //
+ // Search the instance's GroupCtrlBlkList to find the specific address.
+ //
+ NET_LIST_FOR_EACH (ListEntry, &Instance->GroupCtrlBlkList) {
+
+ GroupCtrlBlk = NET_LIST_USER_STRUCT (
+ ListEntry,
+ MNP_GROUP_CONTROL_BLOCK,
+ CtrlBlkEntry
+ );
+ GroupAddress = GroupCtrlBlk->GroupAddress;
+ if (0 == CompareMem (
+ MacAddress,
+ &GroupAddress->Address,
+ SnpMode->HwAddressSize
+ )) {
+ //
+ // There is already the same multicast mac address configured.
+ //
+ AddressExist = TRUE;
+ break;
+ }
+ }
+
+ if (JoinFlag && AddressExist) {
+ //
+ // The multicast mac address to join already exists.
+ //
+ Status = EFI_ALREADY_STARTED;
+ }
+
+ if (!JoinFlag && !AddressExist) {
+ //
+ // The multicast mac address to leave doesn't exist in this instance.
+ //
+ Status = EFI_NOT_FOUND;
+ }
+
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ } else if (IsListEmpty (&Instance->GroupCtrlBlkList)) {
+ //
+ // The MacAddress is NULL and there is no configured multicast mac address,
+ // just return.
+ //
+ goto ON_EXIT;
+ }
+
+ //
+ // OK, it is time to take action.
+ //
+ Status = MnpGroupOp (Instance, JoinFlag, MacAddress, GroupCtrlBlk);
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+/**
+ Places asynchronous outgoing data packets into the transmit queue.
+
+ The Transmit() function places a completion token into the transmit packet
+ queue. This function is always asynchronous.
+ The caller must fill in the Token.Event and Token.TxData fields in the
+ completion token, and these fields cannot be NULL. When the transmit operation
+ completes, the MNP updates the Token.Status field and the Token.Event is
+ signaled.
+ Note: There may be a performance penalty if the packet needs to be
+ defragmented before it can be transmitted by the network device. Systems in
+ which performance is critical should review the requirements and features of
+ the underlying communications device and drivers.
+
+
+ @param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
+ @param[in] Token Pointer to a token associated with the transmit data
+ descriptor. Type EFI_MANAGED_NETWORK_COMPLETION_TOKEN
+ is defined in "Related Definitions" below.
+
+ @retval EFI_SUCCESS The transmit completion token was cached.
+ @retval EFI_NOT_STARTED This MNP child driver instance has not been
+ configured.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is
+ TRUE:
+ * This is NULL.
+ * Token is NULL.
+ * Token.Event is NULL.
+ * Token.TxData is NULL.
+ * Token.TxData.DestinationAddress is not
+ NULL and Token.TxData.HeaderLength is zero.
+ * Token.TxData.FragmentCount is zero.
+ * (Token.TxData.HeaderLength +
+ Token.TxData.DataLength) is not equal to the
+ sum of the
+ Token.TxData.FragmentTable[].FragmentLength
+ fields.
+ * One or more of the
+ Token.TxData.FragmentTable[].FragmentLength
+ fields is zero.
+ * One or more of the
+ Token.TxData.FragmentTable[].FragmentBufferfields
+ is NULL.
+ * Token.TxData.DataLength is greater than MTU.
+ @retval EFI_ACCESS_DENIED The transmit completion token is already in the
+ transmit queue.
+ @retval EFI_OUT_OF_RESOURCES The transmit data could not be queued due to a
+ lack of system resources (usually memory).
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
+ The MNP child driver instance has been reset to
+ startup defaults.
+ @retval EFI_NOT_READY The transmit request could not be queued because
+ the transmit queue is full.
+
+**/
+EFI_STATUS
+EFIAPI
+MnpTransmit (
+ IN EFI_MANAGED_NETWORK_PROTOCOL *This,
+ IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
+ )
+{
+ EFI_STATUS Status;
+ MNP_INSTANCE_DATA *Instance;
+ MNP_SERVICE_DATA *MnpServiceData;
+ UINT8 *PktBuf;
+ UINT32 PktLen;
+ EFI_TPL OldTpl;
+
+ if ((This == NULL) || (Token == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ if (!Instance->Configured) {
+
+ Status = EFI_NOT_STARTED;
+ goto ON_EXIT;
+ }
+
+ if (!MnpIsValidTxToken (Instance, Token)) {
+ //
+ // The Token is invalid.
+ //
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ MnpServiceData = Instance->MnpServiceData;
+ NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
+
+ //
+ // Build the tx packet
+ //
+ Status = MnpBuildTxPacket (MnpServiceData, Token->Packet.TxData, &PktBuf, &PktLen);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // OK, send the packet synchronously.
+ //
+ Status = MnpSyncSendPacket (MnpServiceData, PktBuf, PktLen, Token);
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+
+/**
+ Places an asynchronous receiving request into the receiving queue.
+
+ The Receive() function places a completion token into the receive packet
+ queue. This function is always asynchronous.
+ The caller must fill in the Token.Event field in the completion token, and
+ this field cannot be NULL. When the receive operation completes, the MNP
+ updates the Token.Status and Token.RxData fields and the Token.Event is
+ signaled.
+
+ @param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
+ @param[in] Token Pointer to a token associated with the receive
+ data descriptor. Type
+ EFI_MANAGED_NETWORK_COMPLETION_TOKEN is defined in
+ EFI_MANAGED_NETWORK_PROTOCOL.Transmit().
+
+ @retval EFI_SUCCESS The receive completion token was cached.
+ @retval EFI_NOT_STARTED This MNP child driver instance has not been
+ configured.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is
+ TRUE:
+ * This is NULL.
+ * Token is NULL.
+ * Token.Event is NULL
+ @retval EFI_OUT_OF_RESOURCES The transmit data could not be queued due to a
+ lack of system resources (usually memory).
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
+ The MNP child driver instance has been reset to
+ startup defaults.
+ @retval EFI_ACCESS_DENIED The receive completion token was already in the
+ receive queue.
+ @retval EFI_NOT_READY The receive request could not be queued because
+ the receive queue is full.
+
+**/
+EFI_STATUS
+EFIAPI
+MnpReceive (
+ IN EFI_MANAGED_NETWORK_PROTOCOL *This,
+ IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token
+ )
+{
+ EFI_STATUS Status;
+ MNP_INSTANCE_DATA *Instance;
+ EFI_TPL OldTpl;
+
+ if ((This == NULL) || (Token == NULL) || (Token->Event == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ if (!Instance->Configured) {
+ Status = EFI_NOT_STARTED;
+ goto ON_EXIT;
+ }
+
+ //
+ // Check whether this token(event) is already in the rx token queue.
+ //
+ Status = NetMapIterate (&Instance->RxTokenMap, MnpTokenExist, (VOID *) Token);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Insert the Token into the RxTokenMap.
+ //
+ Status = NetMapInsertTail (&Instance->RxTokenMap, (VOID *) Token, NULL);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Try to deliver any buffered packets.
+ //
+ Status = MnpInstanceDeliverPacket (Instance);
+
+ //
+ // Dispatch the DPC queued by the NotifyFunction of Token->Event.
+ //
+ DispatchDpc ();
+ }
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+/**
+ Aborts an asynchronous transmit or receive request.
+
+ The Cancel() function is used to abort a pending transmit or receive request.
+ If the token is in the transmit or receive request queues, after calling this
+ function, Token.Status will be set to EFI_ABORTED and then Token.Event will be
+ signaled. If the token is not in one of the queues, which usually means that
+ the asynchronous operation has completed, this function will not signal the
+ token and EFI_NOT_FOUND is returned.
+
+ @param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
+ @param[in] Token Pointer to a token that has been issued by
+ EFI_MANAGED_NETWORK_PROTOCOL.Transmit() or
+ EFI_MANAGED_NETWORK_PROTOCOL.Receive(). If NULL, all
+ pending tokens are aborted.
+
+ @retval EFI_SUCCESS The asynchronous I/O request was aborted and
+ Token.Event was signaled. When Token is NULL,
+ all pending requests were aborted and their
+ events were signaled.
+ @retval EFI_NOT_STARTED This MNP child driver instance has not been
+ configured.
+ @retval EFI_INVALID_PARAMETER This is NULL.
+ @retval EFI_NOT_FOUND When Token is not NULL, the asynchronous I/O
+ request was not found in the transmit or
+ receive queue. It has either completed or was
+ not issued by Transmit() and Receive().
+
+**/
+EFI_STATUS
+EFIAPI
+MnpCancel (
+ IN EFI_MANAGED_NETWORK_PROTOCOL *This,
+ IN EFI_MANAGED_NETWORK_COMPLETION_TOKEN *Token OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ MNP_INSTANCE_DATA *Instance;
+ EFI_TPL OldTpl;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ if (!Instance->Configured) {
+ Status = EFI_NOT_STARTED;
+ goto ON_EXIT;
+ }
+
+ //
+ // Iterate the RxTokenMap to cancel the specified Token.
+ //
+ Status = NetMapIterate (&Instance->RxTokenMap, MnpCancelTokens, (VOID *) Token);
+ if (Token != NULL) {
+ Status = (Status == EFI_ABORTED) ? EFI_SUCCESS : EFI_NOT_FOUND;
+ }
+
+ //
+ // Dispatch the DPC queued by the NotifyFunction of the canceled token's events.
+ //
+ DispatchDpc ();
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
+
+/**
+ Polls for incoming data packets and processes outgoing data packets.
+
+ The Poll() function can be used by network drivers and applications to
+ increase the rate that data packets are moved between the communications
+ device and the transmit and receive queues.
+ Normally, a periodic timer event internally calls the Poll() function. But, in
+ some systems, the periodic timer event may not call Poll() fast enough to
+ transmit and/or receive all data packets without missing packets. Drivers and
+ applications that are experiencing packet loss should try calling the Poll()
+ function more often.
+
+ @param[in] This Pointer to the EFI_MANAGED_NETWORK_PROTOCOL instance.
+
+ @retval EFI_SUCCESS Incoming or outgoing data was processed.
+ @retval EFI_NOT_STARTED This MNP child driver instance has not been
+ configured.
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. The
+ MNP child driver instance has been reset to startup
+ defaults.
+ @retval EFI_NOT_READY No incoming or outgoing data was processed. Consider
+ increasing the polling rate.
+ @retval EFI_TIMEOUT Data was dropped out of the transmit and/or receive
+ queue. Consider increasing the polling rate.
+
+**/
+EFI_STATUS
+EFIAPI
+MnpPoll (
+ IN EFI_MANAGED_NETWORK_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ MNP_INSTANCE_DATA *Instance;
+ EFI_TPL OldTpl;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Instance = MNP_INSTANCE_DATA_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ if (!Instance->Configured) {
+ Status = EFI_NOT_STARTED;
+ goto ON_EXIT;
+ }
+
+ //
+ // Try to receive packets.
+ //
+ Status = MnpReceivePacket (Instance->MnpServiceData->MnpDeviceData);
+
+ //
+ // Dispatch the DPC queued by the NotifyFunction of rx token's events.
+ //
+ DispatchDpc ();
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}
|