--- /dev/null
+/** @file\r
+\r
+ Implementation of the SNP.ReceiveFilters() function and its private helpers\r
+ if any.\r
+\r
+ Copyright (C) 2013, Red Hat, Inc.\r
+ Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
+\r
+ This program and the accompanying materials are licensed and made available\r
+ under the terms and conditions of the BSD License which accompanies this\r
+ distribution. The full text of the license may be found at\r
+ http://opensource.org/licenses/bsd-license.php\r
+\r
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT\r
+ WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include "VirtioNet.h"\r
+\r
+/**\r
+ Manages the multicast receive filters of a network interface.\r
+\r
+ @param This The protocol instance pointer.\r
+ @param Enable A bit mask of receive filters to enable on the\r
+ network interface.\r
+ @param Disable A bit mask of receive filters to disable on the\r
+ network interface.\r
+ @param ResetMCastFilter Set to TRUE to reset the contents of the multicast\r
+ receive filters on the network interface to their\r
+ default values.\r
+ @param McastFilterCnt Number of multicast HW MAC addresses in the new\r
+ MCastFilter list. This value must be less than or\r
+ equal to the MCastFilterCnt field of\r
+ EFI_SIMPLE_NETWORK_MODE. This field is optional if\r
+ ResetMCastFilter is TRUE.\r
+ @param MCastFilter A pointer to a list of new multicast receive filter\r
+ HW MAC addresses. This list will replace any\r
+ existing multicast HW MAC address list. This field\r
+ is optional if ResetMCastFilter is TRUE.\r
+\r
+ @retval EFI_SUCCESS The multicast receive filter list was updated.\r
+ @retval EFI_NOT_STARTED The network interface has not been started.\r
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an\r
+ unsupported value.\r
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network\r
+ interface.\r
+ @retval EFI_UNSUPPORTED This function is not supported by the network\r
+ interface.\r
+\r
+**/\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+VirtioNetReceiveFilters (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
+ IN UINT32 Enable,\r
+ IN UINT32 Disable,\r
+ IN BOOLEAN ResetMCastFilter,\r
+ IN UINTN MCastFilterCnt OPTIONAL,\r
+ IN EFI_MAC_ADDRESS *MCastFilter OPTIONAL\r
+ )\r
+{\r
+ VNET_DEV *Dev;\r
+ EFI_TPL OldTpl;\r
+ EFI_STATUS Status;\r
+\r
+ if (This == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ Dev = VIRTIO_NET_FROM_SNP (This);\r
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
+ switch (Dev->Snm.State) {\r
+ case EfiSimpleNetworkStopped:\r
+ Status = EFI_NOT_STARTED;\r
+ goto Exit;\r
+ case EfiSimpleNetworkStarted:\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto Exit;\r
+ default:\r
+ break;\r
+ }\r
+\r
+ //\r
+ // MNP apparently fails to initialize on top of us if we simply return\r
+ // EFI_UNSUPPORTED in this function.\r
+ //\r
+ // Hence we openly refuse multicast functionality, and fake the rest by\r
+ // selecting a no stricter filter setting than whatever is requested. The\r
+ // UEFI-2.3.1+errC spec allows this. In practice we don't change our current\r
+ // (default) filter. Additionally, receiving software is responsible for\r
+ // discarding any packets getting through the filter.\r
+ //\r
+ Status = (\r
+ ((Enable | Disable) & ~Dev->Snm.ReceiveFilterMask) != 0 ||\r
+ (!ResetMCastFilter && MCastFilterCnt > Dev->Snm.MaxMCastFilterCount)\r
+ ) ? EFI_INVALID_PARAMETER : EFI_SUCCESS;\r
+\r
+Exit:\r
+ gBS->RestoreTPL (OldTpl);\r
+ return Status;\r
+}\r