biossnp16.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 2,446 行 · 第 1/5 页
C
2,446 行
PktFilter |= FLTR_DIRECTED;
}
if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) {
PktFilter |= FLTR_DIRECTED;
}
if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) {
PktFilter |= FLTR_BRDCST;
}
if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) {
PktFilter |= FLTR_PRMSCS;
}
if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) {
PktFilter |= FLTR_PRMSCS; // BugBug : Do not know if this is right????
}
//
// BugBug : What is FLTR_SRC_RTG?
//
return PktFilter;
}
//
// Map EFI Multicast filters to UNDI 16 Multicast Filters
//
VOID
Undi16GetMCastFilters(
IN EFI_SIMPLE_NETWORK_MODE *Mode,
IN OUT PXENV_UNDI_MCAST_ADDR_t *McastBuffer,
IN UINTN HwAddressSize
)
{
UINTN Index;
//
// BugBug : What if Mode->MCastFilterCount > MAXNUM_MCADDR?
//
McastBuffer->MCastAddrCount = (UINT16) Mode->MCastFilterCount;
for (Index = 0; Index < MAXNUM_MCADDR; Index++) {
if (Index < McastBuffer->MCastAddrCount) {
EfiCopyMem(&McastBuffer->MCastAddr[Index], &Mode->MCastFilter[Index], HwAddressSize);
} else {
EfiZeroMem(&McastBuffer->MCastAddr[Index], HwAddressSize);
}
}
}
//
// Load 16 bit UNDI Option ROM into memory
//
static
EFI_STATUS
Undi16SimpleNetworkLoadUndi (
EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice
)
{
EFI_STATUS Status;
EFI_PCI_IO_PROTOCOL *PciIo;
UINTN RomAddress;
PCI_EXPANSION_ROM_HEADER *PciExpansionRomHeader;
PCI_DATA_STRUCTURE *PciDataStructure;
PCI_TYPE00 Pci;
CacheVectorAddress (0x1A);
PciIo = SimpleNetworkDevice->PciIo;
Status = PciIo->Pci.Read(
PciIo,
EfiPciIoWidthUint32,
0,
sizeof(Pci) / sizeof (UINT32),
&Pci
);
for(RomAddress = 0xc0000; RomAddress < 0xfffff; RomAddress += 0x800) {
PciExpansionRomHeader = (PCI_EXPANSION_ROM_HEADER *)RomAddress;
if (PciExpansionRomHeader->Signature != PCI_EXPANSION_ROM_HEADER_SIGNATURE) {
continue;
}
DEBUG((EFI_D_INIT,"Option ROM found at %X\n",RomAddress));
PciDataStructure = (PCI_DATA_STRUCTURE *)(RomAddress + PciExpansionRomHeader->PcirOffset);
if (PciDataStructure->Signature != PCI_DATA_STRUCTURE_SIGNATURE) {
continue;
}
DEBUG((EFI_D_INIT,"PCI Data Structure found at %X\n",PciDataStructure));
if (PciDataStructure->VendorId != Pci.Hdr.VendorId || PciDataStructure->DeviceId != Pci.Hdr.DeviceId) {
continue;
}
DEBUG((EFI_D_INIT, "PCI device with matchinng VendorId and DeviceId (%d,%d,%d)\n"));
Status = LaunchBaseCode (SimpleNetworkDevice, RomAddress);
if (!EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
}
return EFI_NOT_FOUND;
}
//
// Unload 16 bit UNDI Option ROM from memory
//
static
EFI_STATUS
Undi16SimpleNetworkUnloadUndi (
EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice
)
{
if (SimpleNetworkDevice->UndiLoaderTable) {
EfiZeroMem (SimpleNetworkDevice->UndiLoaderTable, SimpleNetworkDevice->UndiLoaderTablePages << EFI_PAGE_SIZE);
gBS->FreePages (
(EFI_PHYSICAL_ADDRESS)SimpleNetworkDevice->UndiLoaderTable,
SimpleNetworkDevice->UndiLoaderTablePages
);
}
if (SimpleNetworkDevice->DestinationDataSegment) {
EfiZeroMem (SimpleNetworkDevice->DestinationDataSegment, SimpleNetworkDevice->DestinationDataSegmentPages << EFI_PAGE_SIZE);
gBS->FreePages (
(EFI_PHYSICAL_ADDRESS)SimpleNetworkDevice->DestinationDataSegment,
SimpleNetworkDevice->DestinationDataSegmentPages
);
}
if (SimpleNetworkDevice->DestinationStackSegment) {
EfiZeroMem (SimpleNetworkDevice->DestinationStackSegment, SimpleNetworkDevice->DestinationStackSegmentPages << EFI_PAGE_SIZE);
gBS->FreePages (
(EFI_PHYSICAL_ADDRESS)SimpleNetworkDevice->DestinationStackSegment,
SimpleNetworkDevice->DestinationStackSegmentPages
);
}
if (SimpleNetworkDevice->DestinationCodeSegment) {
EfiZeroMem (SimpleNetworkDevice->DestinationCodeSegment, SimpleNetworkDevice->DestinationCodeSegmentPages << EFI_PAGE_SIZE);
gBS->FreePages (
(EFI_PHYSICAL_ADDRESS)SimpleNetworkDevice->DestinationCodeSegment,
SimpleNetworkDevice->DestinationCodeSegmentPages
);
}
return EFI_SUCCESS;
}
//
// Start the UNDI interface
//
static
EFI_STATUS
Undi16SimpleNetworkStartUndi (
EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice,
UINT16 AX
)
{
EFI_STATUS Status;
PXENV_START_UNDI_t Start;
//
// Call 16 bit UNDI ROM to start the network interface
//
//
// BugBug : What is this state supposed to be???
//
Start.Status = INIT_PXE_STATUS;
Start.ax = AX;
Start.bx = 0x0000;
Start.dx = 0x0000;
Start.di = 0x0000;
Start.es = 0x0000;
Status = PxeStartUndi(SimpleNetworkDevice, &Start);
if (EFI_ERROR(Status)) {
return Status;
}
//
// Check the status code from the 16 bit UNDI ROM
//
if (Start.Status != PXENV_STATUS_SUCCESS) {
return EFI_DEVICE_ERROR;
}
return Status;
}
//
// Stop the UNDI interface
//
static
EFI_STATUS
Undi16SimpleNetworkStopUndi (
EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice
)
{
EFI_STATUS Status;
PXENV_STOP_UNDI_t Stop;
//
// Call 16 bit UNDI ROM to start the network interface
//
Stop.Status = INIT_PXE_STATUS;
Status = PxeUndiStop(SimpleNetworkDevice, &Stop);
if (EFI_ERROR(Status)) {
return Status;
}
//
// Check the status code from the 16 bit UNDI ROM
//
if (Stop.Status != PXENV_STATUS_SUCCESS) {
return EFI_DEVICE_ERROR;
}
return Status;
}
static
EFI_STATUS
Undi16SimpleNetworkStartupUndi (
EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice
)
{
EFI_STATUS Status;
PXENV_UNDI_STARTUP_t Startup;
//
// Call 16 bit UNDI ROM to start the network interface
//
Startup.Status = INIT_PXE_STATUS;
Status = PxeUndiStartup (SimpleNetworkDevice, &Startup);
if (EFI_ERROR(Status)) {
return Status;
}
//
// Check the status code from the 16 bit UNDI ROM
//
if (Startup.Status != PXENV_STATUS_SUCCESS) {
return EFI_DEVICE_ERROR;
}
return Status;
}
static
EFI_STATUS
Undi16SimpleNetworkCleanupUndi (
EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice
)
{
EFI_STATUS Status;
PXENV_UNDI_CLEANUP_t Cleanup;
//
// Call 16 bit UNDI ROM to cleanup the network interface
//
Cleanup.Status = INIT_PXE_STATUS;
Status = PxeUndiCleanup(SimpleNetworkDevice, &Cleanup);
if (EFI_ERROR(Status)) {
return Status;
}
//
// Check the status code from the 16 bit UNDI ROM
//
if (Cleanup.Status != PXENV_STATUS_SUCCESS) {
return EFI_DEVICE_ERROR;
}
return Status;
}
//
// GetInformation()
//
static
EFI_STATUS
Undi16SimpleNetworkGetInformation (
IN EFI_SIMPLE_NETWORK_PROTOCOL *This
)
{
EFI_STATUS Status;
EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
UINTN Index;
if (!This) {
return EFI_INVALID_PARAMETER;
}
Status = EFI_SUCCESS;
SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS(This);
if (!SimpleNetworkDevice) {
return EFI_DEVICE_ERROR;
}
//
// Verify that the current state of the adapter is valid for this call.
//
switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
case EfiSimpleNetworkStarted:
case EfiSimpleNetworkInitialized:
break;
case EfiSimpleNetworkStopped:
return EFI_NOT_STARTED;
default:
return EFI_DEVICE_ERROR;
}
//
// Call 16 bit UNDI ROM to start the network interface
//
EfiZeroMem(&SimpleNetworkDevice->GetInformation, sizeof(PXENV_UNDI_GET_INFORMATION_t));
SimpleNetworkDevice->GetInformation.Status = INIT_PXE_STATUS;
Status = PxeUndiGetInformation (SimpleNetworkDevice, &SimpleNetworkDevice->GetInformation);
if (EFI_ERROR(Status)) {
return Status;
}
DEBUG((EFI_D_NET," GetInformation.Status = %d\n",SimpleNetworkDevice->GetInformation.Status));
DEBUG((EFI_D_NET," GetInformation.BaseIo = %d\n",SimpleNetworkDevice->GetInformation.BaseIo));
DEBUG((EFI_D_NET," GetInformation.IntNumber = %d\n",SimpleNetworkDevice->GetInformation.IntNumber));
DEBUG((EFI_D_NET," GetInformation.MaxTranUnit = %d\n",SimpleNetworkDevice->GetInformation.MaxTranUnit));
DEBUG((EFI_D_NET," GetInformation.HwType = %d\n",SimpleNetworkDevice->GetInformation.HwType));
DEBUG((EFI_D_NET," GetInformation.HwAddrLen = %d\n",SimpleNetworkDevice->GetInformation.HwAddrLen));
DEBUG((EFI_D_NET," GetInformation.ROMAddress = %d\n",SimpleNetworkDevice->GetInformation.ROMAddress));
DEBUG((EFI_D_NET," GetInformation.RxBufCt = %d\n",SimpleNetworkDevice->GetInformation.RxBufCt));
DEBUG((EFI_D_NET," GetInformation.TxBufCt = %d\n",SimpleNetworkDevice->GetInformation.TxBufCt));
DEBUG((EFI_D_NET," GetInformation.CurNodeAddr ="));
for(Index = 0; Index < 16; Index++) {
DEBUG((EFI_D_NET,"%02x ",SimpleNetworkDevice->GetInformation.CurrentNodeAddress[Index]));
}
DEBUG((EFI_D_NET,"\n"));
DEBUG((EFI_D_NET," GetInformation.PermNodeAddr ="));
for(Index = 0; Index < 16; Index++) {
DEBUG((EFI_D_NET,"%02x ",SimpleNetworkDevice->GetInformation.PermNodeAddress[Index]));
}
DEBUG((EFI_D_NET,"\n"));
//
// Check the status code from the 16 bit UNDI ROM
//
if (SimpleNetworkDevice->GetInformation.Status != PXENV_STATUS_SUCCESS) {
return EFI_DEVICE_ERROR;
}
//
// The information has been retrieved. Fill in Mode data.
//
SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize =
SimpleNetworkDevice->GetInformation.HwAddrLen;
SimpleNetworkDevice->SimpleNetworkMode.MaxPacketSize =
SimpleNetworkDevice->GetInformation.MaxTranUnit;
SimpleNetworkDevice->SimpleNetworkMode.IfType =
(UINT8)SimpleNetworkDevice->GetInformation.HwType;
EfiZeroMem(&SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,
sizeof SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress);
EfiCopyMem(&SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,
&SimpleNetworkDevice->GetInformation.CurrentNodeAddress,
SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize);
EfiZeroMem(&SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,
sizeof SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress);
EfiCopyMem(&SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,
&SimpleNetworkDevice->GetInformation.PermNodeAddress,
SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize);
// hard code broadcast address - not avail in PXE2.1
EfiZeroMem(&SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress,
sizeof SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress);
EfiSetMem(&SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress,
SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize, 0xff);
return Status;
}
static
EFI_STATUS
Undi16SimpleNetworkGetNicType (
IN EFI_SIMPLE_NETWORK_PROTOCOL *This
)
{
EFI_STATUS Status;
EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
if (!This) {
return EFI_INVALID_PARAMETER;
}
Status = EFI_SUCCESS;
SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS(This);
if (!SimpleNetworkDevice) {
return EFI_DEVICE_ERROR;
}
EfiZeroMem(&SimpleNetworkDevice->GetNicType, sizeof(PXENV_UNDI_GET_NIC_TYPE_t));
SimpleNetworkDevice->GetNicType.Status = INIT_PXE_STATUS;
Status = PxeUndiGetNicType(SimpleNetworkDevice, &SimpleNetworkDevice->GetNicType);
if (EFI_ERROR(Status)) {
return Status;
}
DEBUG((EFI_D_NET," GetNicType.Status = %d\n",SimpleNetworkDevice->GetNicType.Status));
DEBUG((EFI_D_NET," GetNicType.NicType = %d\n",SimpleNetworkDevice->GetNicType.NicType));
//
// Check the status code from the 16 bit UNDI ROM
//
if (SimpleNetworkDevice->GetNicType.Status != PXENV_STATUS_SUCCESS) {
return EFI_DEVICE_ERROR;
}
//
// The information has been retrieved. Fill in Mode data.
//
return Status;
}
static
EFI_STATUS
Undi16SimpleNetworkGetNdisInfo (
IN EFI_SIMPLE_NETWORK_PROTOCOL *This
)
{
EFI_STATUS Status;
EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
if (!This) {
return EFI_INVALID_PARAMETER;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?