mnpconfig.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 1,577 行 · 第 1/3 页
C
1,577 行
if (OldConfigData->EnableBroadcastReceive) {
MnpServiceData->BroadcastCount--;
}
if (OldConfigData->EnablePromiscuousReceive) {
MnpServiceData->PromiscuousCount--;
}
//
// Set the receive filter counters and the receive filter of the
// instance according to the new ConfigData.
//
if (NewConfigData->EnableUnicastReceive) {
MnpServiceData->UnicastCount++;
Instance->ReceiveFilter |= MNP_RECEIVE_UNICAST;
}
if (NewConfigData->EnableMulticastReceive) {
MnpServiceData->MulticastCount++;
}
if (NewConfigData->EnableBroadcastReceive) {
MnpServiceData->BroadcastCount++;
Instance->ReceiveFilter |= MNP_RECEIVE_BROADCAST;
}
if (NewConfigData->EnablePromiscuousReceive) {
MnpServiceData->PromiscuousCount++;
}
if (EFI_ERROR (NET_TRYLOCK (&Instance->RxLock))) {
return EFI_ACCESS_DENIED;
}
if (OldConfigData->FlushQueuesOnReset) {
MnpFlushRcvdDataQueue (Instance);
}
if (ConfigData == NULL) {
NetMapIterate (&Instance->RxTokenMap, MnpCancelTokens, NULL);
}
NET_UNLOCK (&Instance->RxLock);
if (!NewConfigData->EnableMulticastReceive) {
if (EFI_ERROR (NET_TRYLOCK (&MnpServiceData->GroupAddressLock))) {
return EFI_ACCESS_DENIED;
}
MnpGroupOp (Instance, FALSE, NULL, NULL);
NET_UNLOCK (&MnpServiceData->GroupAddressLock);
}
//
// Save the new configuration data.
//
*OldConfigData = *NewConfigData;
Instance->Configured = (BOOLEAN) (ConfigData != NULL);
if (Instance->Configured) {
//
// The instance is configured, start the Mnp.
//
Status = MnpStart (
MnpServiceData,
IsConfigUpdate,
!NewConfigData->DisableBackgroundPolling
);
} else {
//
// The instance is changed to the unconfigured state, stop the Mnp.
//
Status = MnpStop (MnpServiceData);
}
return Status;
}
STATIC
EFI_STATUS
MnpConfigReceiveFilters (
IN MNP_SERVICE_DATA *MnpServiceData
)
/*++
Routine Description:
Configure the Snp receive filters according to the instances' receive filter
settings.
Arguments:
MnpServiceData - Pointer to the mnp service context data.
Returns:
EFI_SUCCESS - The receive filters is configured.
EFI_OUT_OF_RESOURCES - The receive filters can't be configured due to lack of
memory resource.
--*/
{
EFI_STATUS Status;
EFI_SIMPLE_NETWORK_PROTOCOL *Snp;
EFI_MAC_ADDRESS *MCastFilter;
UINT32 MCastFilterCnt;
UINT32 EnableFilterBits;
UINT32 DisableFilterBits;
BOOLEAN ResetMCastFilters;
NET_LIST_ENTRY *Entry;
UINT32 Index;
MNP_GROUP_ADDRESS *GroupAddress;
NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
Snp = MnpServiceData->Snp;
//
// Initialize the enable filter and disable filter.
//
EnableFilterBits = 0;
DisableFilterBits = Snp->Mode->ReceiveFilterMask;
if (MnpServiceData->UnicastCount != 0) {
//
// Enable unicast if any instance wants to receive unicast.
//
EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
}
if (MnpServiceData->BroadcastCount != 0) {
//
// Enable broadcast if any instance wants to receive broadcast.
//
EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
}
MCastFilter = NULL;
MCastFilterCnt = 0;
ResetMCastFilters = TRUE;
if ((MnpServiceData->MulticastCount != 0) && (MnpServiceData->GroupAddressCount != 0)) {
//
// There are instances configured to receive multicast and already some group
// addresses are joined.
//
ResetMCastFilters = FALSE;
if (MnpServiceData->GroupAddressCount <= Snp->Mode->MaxMCastFilterCount) {
//
// The joind group address is less than simple network's maximum count.
// Just configure the snp to do the multicast filtering.
//
EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;
//
// Allocate pool for the mulicast addresses.
//
MCastFilterCnt = MnpServiceData->GroupAddressCount;
MCastFilter = NetAllocatePool (sizeof (EFI_MAC_ADDRESS) * MCastFilterCnt);
if (MCastFilter == NULL) {
MNP_DEBUG_ERROR (("MnpConfigReceiveFilters: Failed to allocate memory"" resource for MCastFilter.\n"));
return EFI_OUT_OF_RESOURCES;
}
//
// Fill the multicast HW address buffer.
//
Index = 0;
NET_LIST_FOR_EACH (Entry, &MnpServiceData->GroupAddressList) {
GroupAddress = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_ADDRESS, AddrEntry);
*(MCastFilter + Index) = GroupAddress->Address;
Index++;
ASSERT (Index <= MCastFilterCnt);
}
} else {
//
// The maximum multicast is reached, set the filter to be promiscuous
// multicast.
//
if (Snp->Mode->ReceiveFilterMask & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) {
EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
} else {
//
// Either MULTICAST or PROMISCUOUS_MULTICAST is not supported by Snp,
// set the NIC to be promiscuous although this will tremendously degrade
// the performance.
//
EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
}
}
}
if (MnpServiceData->PromiscuousCount != 0) {
//
// Enable promiscuous if any instance wants to receive promiscuous.
//
EnableFilterBits |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
}
//
// Set the disable filter.
//
DisableFilterBits ^= EnableFilterBits;
//
// Configure the receive filters of SNP.
//
Status = Snp->ReceiveFilters (
Snp,
EnableFilterBits,
DisableFilterBits,
ResetMCastFilters,
MCastFilterCnt,
MCastFilter
);
DEBUG_CODE (
if (EFI_ERROR (Status)) {
MNP_DEBUG_ERROR (
("MnpConfigReceiveFilters: Snp->ReceiveFilters ""failed, %r.\n",
Status)
);
}
);
if (MCastFilter != NULL) {
//
// Free the buffer used to hold the group addresses.
//
NetFreePool (MCastFilter);
}
return Status;
}
STATIC
EFI_STATUS
MnpGroupOpAddCtrlBlk (
IN MNP_INSTANCE_DATA *Instance,
IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk,
IN MNP_GROUP_ADDRESS *GroupAddress OPTIONAL,
IN EFI_MAC_ADDRESS *MacAddress,
IN UINT32 HwAddressSize
)
/*++
Routine Description:
Add a group address control block which controls the MacAddress for
this instance.
Arguments:
Instance - Pointer to the mnp instance context data.
CtrlBlk - Pointer to the group address control block.
GroupAddress - Pointer to the group adress.
MacAddress - Pointer to the mac address.
HwAddressSize - The hardware address size.
Returns:
EFI_SUCCESS - The group address control block is added.
EFI_OUT_OF_RESOURCE - Failed due to lack of memory resources.
--*/
{
MNP_SERVICE_DATA *MnpServiceData;
NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
MnpServiceData = Instance->MnpServiceData;
NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
if (GroupAddress == NULL) {
ASSERT (MacAddress != NULL);
//
// Allocate a new GroupAddress to be added into MNP's GroupAddressList.
//
GroupAddress = NetAllocatePool (sizeof (MNP_GROUP_ADDRESS));
if (GroupAddress == NULL) {
MNP_DEBUG_ERROR (("MnpGroupOpFormCtrlBlk: Failed to allocate memory ""resource.\n"));
return EFI_OUT_OF_RESOURCES;
}
GroupAddress->Address = *MacAddress;
GroupAddress->RefCnt = 0;
NetListInsertTail (
&MnpServiceData->GroupAddressList,
&GroupAddress->AddrEntry
);
MnpServiceData->GroupAddressCount++;
}
//
// Increase the RefCnt.
//
GroupAddress->RefCnt++;
//
// Add the CtrlBlk into the instance's GroupCtrlBlkList.
//
CtrlBlk->GroupAddress = GroupAddress;
NetListInsertTail (&Instance->GroupCtrlBlkList, &CtrlBlk->CtrlBlkEntry);
return EFI_SUCCESS;
}
STATIC
BOOLEAN
MnpGroupOpDelCtrlBlk (
IN MNP_INSTANCE_DATA *Instance,
IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk
)
/*++
Routine Description:
Delete a group control block from the instance. If the controlled group address's
reference count reaches zero, the group address is removed too.
Arguments:
Instance - Pointer to the instance context data.
CtrlBlk - Pointer to the group control block to delete.
Returns:
The group address controlled by the control block is no longer used or not.
--*/
{
MNP_SERVICE_DATA *MnpServiceData;
MNP_GROUP_ADDRESS *GroupAddress;
NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
MnpServiceData = Instance->MnpServiceData;
NET_CHECK_SIGNATURE (MnpServiceData, MNP_SERVICE_DATA_SIGNATURE);
//
// Remove and free the CtrlBlk.
//
GroupAddress = CtrlBlk->GroupAddress;
NetListRemoveEntry (&CtrlBlk->CtrlBlkEntry);
NetFreePool (CtrlBlk);
ASSERT (GroupAddress->RefCnt > 0);
//
// Count down the RefCnt.
//
GroupAddress->RefCnt--;
if (GroupAddress->RefCnt == 0) {
//
// Free this GroupAddress entry if no instance uses it.
//
MnpServiceData->GroupAddressCount--;
NetListRemoveEntry (&GroupAddress->AddrEntry);
NetFreePool (GroupAddress);
return TRUE;
}
return FALSE;
}
EFI_STATUS
MnpGroupOp (
IN MNP_INSTANCE_DATA *Instance,
IN BOOLEAN JoinFlag,
IN EFI_MAC_ADDRESS *MacAddress OPTIONAL,
IN MNP_GROUP_CONTROL_BLOCK *CtrlBlk OPTIONAL
)
/*++
Routine Description:
Do the group operations for this instance.
Arguments:
Instance - Pointer to the instance context data.
JoinFlag - Set to TRUE to join a group. Set to TRUE to leave a group/groups.
MacAddress - Pointer to the group address to join or leave.
CtrlBlk - Pointer to the group control block if JoinFlag if FALSE.
Returns:
EFI_SUCCESS - The group operation finished.
Other - Some error occurs.
--*/
{
MNP_SERVICE_DATA *MnpServiceData;
NET_LIST_ENTRY *Entry;
NET_LIST_ENTRY *NextEntry;
MNP_GROUP_ADDRESS *GroupAddress;
EFI_SIMPLE_NETWORK_MODE *SnpMode;
MNP_GROUP_CONTROL_BLOCK *NewCtrlBlk;
EFI_STATUS Status;
BOOLEAN AddressExist;
BOOLEAN NeedUpdate;
NET_CHECK_SIGNATURE (Instance, MNP_INSTANCE_DATA_SIGNATURE);
MnpServiceData = Instance->MnpServiceData;
SnpMode = MnpServiceData->Snp->Mode;
if (JoinFlag) {
//
// A new gropu address is to be added.
//
GroupAddress = NULL;
AddressExist = FALSE;
//
// Allocate memory for the control block.
//
NewCtrlBlk = NetAllocatePool (sizeof (MNP_GROUP_CONTROL_BLOCK));
if (NewCtrlBlk == NULL) {
MNP_DEBUG_ERROR (("MnpGroupOp: Failed to allocate memory resource.\n"));
return EFI_OUT_OF_RESOURCES;
}
NET_LIST_FOR_EACH (Entry, &MnpServiceData->GroupAddressList) {
//
// Check whether the MacAddress is already joined by other instances.
//
GroupAddress = NET_LIST_USER_STRUCT (Entry, MNP_GROUP_ADDRESS, AddrEntry);
if (0 == NetCompareMem (
MacAddress,
&GroupAddress->Address,
SnpMode->HwAddressSize
)) {
AddressExist = TRUE;
break;
}
}
if (!AddressExist) {
GroupAddress = NULL;
}
//
// Add the GroupAddress for this instance.
//
Status = MnpGroupOpAddCtrlBlk (
Instance,
NewCtrlBlk,
GroupAddress,
MacAddress,
SnpMode->HwAddressSize
);
if (EFI_ERROR (Status)) {
return Status;
}
NeedUpdate = TRUE;
} else {
if (MacAddress != NULL) {
ASSERT (CtrlBlk != NULL);
//
// Leave the specific multicast mac address.
//
NeedUpdate = MnpGroupOpDelCtrlBlk (Instance, CtrlBlk);
} else {
//
// Leave all multicast mac addresses.
//
NeedUpdate = FALSE;
NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &Instance->GroupCtrlBlkList) {
NewCtrlBlk = NET_LIST_USER_STRUCT (
Entry,
MNP_GROUP_CONTROL_BLOCK,
CtrlBlkEntry
);
//
// Update is required if the group address left is no longer used
// by other instances.
//
NeedUpdate = MnpGroupOpDelCtrlBlk (Instance, NewCtrlBlk);
}
}
}
Status = EFI_SUCCESS;
if (NeedUpdate) {
//
// Reconfigure the receive filters if necessary.
//
Status = MnpConfigReceiveFilters (MnpServiceData);
}
return Status;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?