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