biossnp16.c

来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 2,446 行 · 第 1/5 页

C
2,446
字号

{
	EFI_STATUS              Status;
	EFI_SIMPLE_NETWORK_DEV  *SimpleNetworkDevice;
	PXENV_UNDI_RESET_t      Reset; 
	UINT16 rx_filter;

	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 EfiSimpleNetworkStopped:
		return EFI_NOT_STARTED;

	case EfiSimpleNetworkInitialized:
		break;

	case EfiSimpleNetworkStarted:
	default:
		return EFI_DEVICE_ERROR;
	}

	Reset.Status = INIT_PXE_STATUS;

	rx_filter = Undi16GetPacketFilterSetting(SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting);

	Undi16GetMCastFilters(&SimpleNetworkDevice->SimpleNetworkMode,
		&Reset.R_Mcast_Buf,
		SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize);

	Status = PxeUndiResetNic(SimpleNetworkDevice, &Reset, rx_filter);

	if (EFI_ERROR(Status)) {
		return Status;
	}

	//
	// Check the status code from the 16 bit UNDI ROM
	//

	if (Reset.Status != PXENV_STATUS_SUCCESS) {
		return EFI_DEVICE_ERROR;
	}

	//
	// Reset the recycled transmit buffer FIFO
	//

	SimpleNetworkDevice->TxBufferFifo.First = 0;
	SimpleNetworkDevice->TxBufferFifo.Last = 0;
	SimpleNetworkDevice->IsrValid = FALSE;

	return Status;
}

//
// Shutdown()
//

EFI_STATUS
Undi16SimpleNetworkShutdown (
	IN EFI_SIMPLE_NETWORK_PROTOCOL  *This
)

{
	EFI_STATUS              Status;
	EFI_SIMPLE_NETWORK_DEV  *SimpleNetworkDevice;
	PXENV_UNDI_CLOSE_t      Close; 
	PXENV_UNDI_SHUTDOWN_t   Shutdown; 

	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 EfiSimpleNetworkStopped:
		return EFI_NOT_STARTED;

	case EfiSimpleNetworkInitialized:
		break;

	case EfiSimpleNetworkStarted:
	default:
		return EFI_DEVICE_ERROR;
	}

	SimpleNetworkDevice->IsrValid = FALSE;

	//
	// Call 16 bit UNDI ROM to start the network interface
	//

	Close.Status = INIT_PXE_STATUS;

	Status = PxeUndiClose(SimpleNetworkDevice, &Close);

	if (EFI_ERROR(Status)) {
		return Status;
	}

	//
	// Check the status code from the 16 bit UNDI ROM
	//

	if (Close.Status != PXENV_STATUS_SUCCESS) {
		return EFI_DEVICE_ERROR;
	}

	//
	// Call 16 bit UNDI ROM to open the network interface
	//

	Shutdown.Status = INIT_PXE_STATUS;

	Status = PxeUndiShutdown(SimpleNetworkDevice, &Shutdown);

	if (EFI_ERROR(Status)) {
		return Status;
	}

	//
	// Check the status code from the 16 bit UNDI ROM
	//

	if (Shutdown.Status != PXENV_STATUS_SUCCESS) {
		return EFI_DEVICE_ERROR;
	}

	//
	// The UNDI interface has been initialized, so update the State.
	//

	SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkStarted;

	//
	// If shutdown succeeds, then assume that media is not present.
	//

	SimpleNetworkDevice->SimpleNetworkMode.MediaPresent = FALSE;

	//
	// Reset the recycled transmit buffer FIFO
	//

	SimpleNetworkDevice->TxBufferFifo.First = 0;
	SimpleNetworkDevice->TxBufferFifo.Last  = 0;

	//
	// A short delay.  Without this an initialize immediately following
	// a shutdown will cause some versions of UNDI-16 to stop operating.
	//

	gBS->Stall(250000);

	return Status;
}

//
// ReceiveFilters()
//

EFI_STATUS
Undi16SimpleNetworkReceiveFilters (
	IN EFI_SIMPLE_NETWORK_PROTOCOL           *This,
	IN UINT32                       Enable,
	IN UINT32                       Disable,
	IN BOOLEAN                      ResetMCastFilter,
	IN UINTN                        MCastFilterCnt     OPTIONAL,
	IN EFI_MAC_ADDRESS  *MCastFilter       OPTIONAL
)

{
	EFI_STATUS                      Status;
	UINTN                           i;
	UINT32                          NewFilter;
	EFI_SIMPLE_NETWORK_DEV          *SimpleNetworkDevice;
	PXENV_UNDI_CLOSE_t              Close; 
	PXENV_UNDI_OPEN_t               Open; 

	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 EfiSimpleNetworkStopped:
		return EFI_NOT_STARTED;

	case EfiSimpleNetworkInitialized:
		break;

	case EfiSimpleNetworkStarted:
	default:
		return EFI_DEVICE_ERROR;
	}

	//
	// First deal with possible filter setting changes
	//

	if (!Enable && !Disable && !ResetMCastFilter) {
		return EFI_SUCCESS;
	}

	NewFilter = (SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting | Enable) & ~Disable;

	if (NewFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) {
		if (!MCastFilterCnt || !MCastFilter ||
			MCastFilterCnt > SimpleNetworkDevice->SimpleNetworkMode.MaxMCastFilterCount)
		{
			return EFI_INVALID_PARAMETER;
		}
	}

	//
	// Call 16 bit UNDI ROM to close the network interface
	//

	Close.Status      = INIT_PXE_STATUS;

	Status = PxeUndiClose(SimpleNetworkDevice, &Close);

	if (EFI_ERROR(Status)) {
		return Status;
	}

	//
	// Check the status code from the 16 bit UNDI ROM
	//

	if (Close.Status != PXENV_STATUS_SUCCESS) {
		return EFI_DEVICE_ERROR;
	}

	//
	// Call 16 bit UNDI ROM to open the network interface
	//

	//
	// Reset the recycled transmit buffer FIFO
	//

	SimpleNetworkDevice->TxBufferFifo.First = 0;
	SimpleNetworkDevice->TxBufferFifo.Last  = 0;

	//
	// Call 16 bit UNDI ROM to open the network interface
	//

	EfiZeroMem(&Open, sizeof Open);

	Open.Status   = INIT_PXE_STATUS;
	Open.PktFilter = Undi16GetPacketFilterSetting(NewFilter);

	if (NewFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) {
		// Copy the MAC addresses into the UNDI open parameter structure
		Open.McastBuffer.MCastAddrCount = (UINT16)MCastFilterCnt;
		for (i = 0; i < MCastFilterCnt; ++i) {
			EfiCopyMem(Open.McastBuffer.MCastAddr[i], &MCastFilter[i],
				sizeof Open.McastBuffer.MCastAddr[i]);
		}
	} else if (!ResetMCastFilter) {
		for (i = 0; i < SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount; ++i) {
			EfiCopyMem(Open.McastBuffer.MCastAddr[i],
				&SimpleNetworkDevice->SimpleNetworkMode.MCastFilter[i],
				sizeof Open.McastBuffer.MCastAddr[i]);
		}
	}

	Status = PxeUndiOpen(SimpleNetworkDevice, &Open);

	if (EFI_ERROR(Status)) {
		return Status;
	}

	//
	// Check the status code from the 16 bit UNDI ROM
	//

	if (Open.Status != PXENV_STATUS_SUCCESS) {
		return EFI_DEVICE_ERROR;
	}

	SimpleNetworkDevice->IsrValid = FALSE;
	SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting = NewFilter;

	if (NewFilter & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) {
		SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount = (UINT32)MCastFilterCnt;
		for (i = 0; i < MCastFilterCnt; ++i) {
			SimpleNetworkDevice->SimpleNetworkMode.MCastFilter[i] = MCastFilter[i];
		}
	}

	//
	// Read back multicast addresses.
	//

	return EFI_SUCCESS;
}

//
// StationAddress()
//

EFI_STATUS
Undi16SimpleNetworkStationAddress (
	IN EFI_SIMPLE_NETWORK_PROTOCOL           *This,
	IN BOOLEAN                      Reset,
	IN EFI_MAC_ADDRESS  *New      OPTIONAL
)

{
	EFI_STATUS              Status;
	EFI_SIMPLE_NETWORK_DEV  *SimpleNetworkDevice;
	PXENV_UNDI_SET_STATION_ADDR_t  SetStationAddr;  
	//EFI_DEVICE_PATH_PROTOCOL     *OldDevicePath;
	PXENV_UNDI_CLOSE_t      close; 
	PXENV_UNDI_OPEN_t	open;

	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 EfiSimpleNetworkInitialized:
		break;

	case EfiSimpleNetworkStopped:
		return EFI_NOT_STARTED;

	case EfiSimpleNetworkStarted:
	default:
		return EFI_DEVICE_ERROR;
	}

	//
	// Call 16 bit UNDI ROM to open the network interface
	//

	SetStationAddr.Status = INIT_PXE_STATUS;

	if (Reset) {

		//
		// If we are reseting the Station Address to the permanent address, and the 
		// Station Address is not programmable, then just return EFI_SUCCESS.
		//

		if (SimpleNetworkDevice->SimpleNetworkMode.MacAddressChangeable == FALSE) {
			return EFI_SUCCESS;
		}

		//
		// If the address is already the permanent address, then just return success.
		//

		if (!EfiCompareMem(&SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,
			&SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,
			SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize))
		{
			return EFI_SUCCESS;
		}

		//
		// Copy the adapters permanent address to the new station address
		//

		EfiCopyMem(&SetStationAddr.StationAddress, 
			&SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress,
			SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize);
	} else {
		//
		// If we are setting the Station Address, and the 
		// Station Address is not programmable, return invalid parameter.
		//

		if (SimpleNetworkDevice->SimpleNetworkMode.MacAddressChangeable == FALSE) {
			return EFI_INVALID_PARAMETER;
		}

		//
		// If the address is already the new address, then just return success.
		//

		if (!EfiCompareMem(&SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,
			New, SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize))
		{ 
			return EFI_SUCCESS;
		}

		//
		// Copy New to the new station address
		//

		EfiCopyMem(&SetStationAddr.StationAddress, New,
			SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize);

	}

	//
	// Call 16 bit UNDI ROM to stop the network interface
	//

	close.Status = INIT_PXE_STATUS;

	PxeUndiClose(SimpleNetworkDevice, &close);

	//
	// Call 16-bit UNDI ROM to set the station address
	//

	SetStationAddr.Status = PXENV_STATUS_SUCCESS;

	Status = PxeUndiSetStationAddr(SimpleNetworkDevice, &SetStationAddr);

	//
	// Call 16-bit UNDI ROM to start the network interface
	//

	open.Status = PXENV_STATUS_SUCCESS;
	open.OpenFlag = 0;
	open.PktFilter = Undi16GetPacketFilterSetting(SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting);
	Undi16GetMCastFilters(&SimpleNetworkDevice->SimpleNetworkMode,
		&open.McastBuffer,
		SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize);

	PxeUndiOpen(SimpleNetworkDevice, &open);

	//
	// Check status from station address change
	//

	if (EFI_ERROR(Status)) {
		return Status;
	}

	//
	// Check the status code from the 16 bit UNDI ROM
	//

	if (SetStationAddr.Status != PXENV_STATUS_SUCCES

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?