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 + -
显示快捷键?