biossnp16.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 2,446 行 · 第 1/5 页
C
2,446 行
}
Status = EFI_SUCCESS;
SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS(This);
if (!SimpleNetworkDevice) {
return EFI_DEVICE_ERROR;
}
EfiZeroMem(&SimpleNetworkDevice->GetNdisInfo, sizeof(PXENV_UNDI_GET_NDIS_INFO_t));
SimpleNetworkDevice->GetNdisInfo.Status = INIT_PXE_STATUS;
Status = PxeUndiGetNdisInfo (SimpleNetworkDevice, &SimpleNetworkDevice->GetNdisInfo);
if (EFI_ERROR(Status)) {
return Status;
}
DEBUG((EFI_D_NET," GetNdisInfo.Status = %d\n",SimpleNetworkDevice->GetNdisInfo.Status));
DEBUG((EFI_D_NET," GetNdisInfo.IfaceType = %a\n",SimpleNetworkDevice->GetNdisInfo.IfaceType));
DEBUG((EFI_D_NET," GetNdisInfo.LinkSpeed = %d\n",SimpleNetworkDevice->GetNdisInfo.LinkSpeed));
DEBUG((EFI_D_NET," GetNdisInfo.ServiceFlags = %08x\n",SimpleNetworkDevice->GetNdisInfo.ServiceFlags));
//
// Check the status code from the 16 bit UNDI ROM
//
if (SimpleNetworkDevice->GetNdisInfo.Status != PXENV_STATUS_SUCCESS) {
return EFI_DEVICE_ERROR;
}
//
// The information has been retrieved. Fill in Mode data.
//
return Status;
}
//
// Isr()
//
EFI_STATUS
Undi16SimpleNetworkIsr (
IN EFI_SIMPLE_NETWORK_PROTOCOL *This ,
IN UINTN *FrameLength,
IN UINTN *FrameHeaderLength, OPTIONAL
IN UINT8 *Frame, OPTIONAL
IN UINT8 *ProtType, OPTIONAL
IN UINT8 *PktType OPTIONAL
)
{
EFI_STATUS Status;
EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
BOOLEAN FrameReceived;
if (!This) {
return EFI_INVALID_PARAMETER;
}
Status = EFI_SUCCESS;
SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS(This);
if (!SimpleNetworkDevice) {
return EFI_DEVICE_ERROR;
}
FrameReceived = FALSE;
//
// 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;
}
DEBUG((EFI_D_NET, "Isr() IsrValid = %d\n",SimpleNetworkDevice->IsrValid));
if (SimpleNetworkDevice->IsrValid == FALSE) {
//
// Call 16 bit UNDI ROM to open the network interface
//
EfiZeroMem(&SimpleNetworkDevice->Isr,sizeof(PXENV_UNDI_ISR_t));
SimpleNetworkDevice->Isr.Status = INIT_PXE_STATUS;
SimpleNetworkDevice->Isr.FuncFlag = PXENV_UNDI_ISR_IN_START;
DEBUG((EFI_D_NET, "Isr() START\n"));
Status = PxeUndiIsr (SimpleNetworkDevice, &SimpleNetworkDevice->Isr);
if (EFI_ERROR(Status)) {
return Status;
}
//
// Check the status code from the 16 bit UNDI ROM
//
if (SimpleNetworkDevice->Isr.Status != PXENV_STATUS_SUCCESS) {
return EFI_DEVICE_ERROR;
}
//
// There have been no events on this UNDI interface, so return EFI_NOT_READY
//
if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_NOT_OURS) {
return EFI_SUCCESS;
}
//
// There is data to process, so call until all events processed.
//
EfiZeroMem(&SimpleNetworkDevice->Isr,sizeof(PXENV_UNDI_ISR_t));
SimpleNetworkDevice->Isr.Status = INIT_PXE_STATUS;
SimpleNetworkDevice->Isr.FuncFlag = PXENV_UNDI_ISR_IN_PROCESS;
DEBUG((EFI_D_NET, "Isr() PROCESS\n"));
Status = PxeUndiIsr (SimpleNetworkDevice, &SimpleNetworkDevice->Isr);
if (EFI_ERROR(Status)) {
return Status;
}
SimpleNetworkDevice->IsrValid = TRUE;
}
//
// Call UNDI GET_NEXT until DONE
//
while (SimpleNetworkDevice->Isr.FuncFlag != PXENV_UNDI_ISR_OUT_DONE) {
//
// Check the status code from the 16 bit UNDI ROM
//
if (SimpleNetworkDevice->Isr.Status != PXENV_STATUS_SUCCESS) {
return EFI_DEVICE_ERROR;
}
//
// UNDI is busy. Caller will have to call again.
// This should never happen with a polled mode driver.
//
if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_BUSY) {
DEBUG((EFI_D_NET," BUSY\n"));
return EFI_SUCCESS;
}
//
// Check for invalud UNDI FuncFlag
//
if (SimpleNetworkDevice->Isr.FuncFlag != PXENV_UNDI_ISR_OUT_RECEIVE && SimpleNetworkDevice->Isr.FuncFlag != PXENV_UNDI_ISR_OUT_TRANSMIT) {
DEBUG((EFI_D_NET," Invalid SimpleNetworkDevice->Isr.FuncFlag value %d\n",SimpleNetworkDevice->Isr.FuncFlag));
return EFI_DEVICE_ERROR;
}
//
// Check for Transmit Event
//
if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_TRANSMIT) {
DEBUG((EFI_D_NET," TRANSMIT\n"));
SimpleNetworkDevice->InterruptStatus |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
}
//
// Check for Receive Event
//
else
if (SimpleNetworkDevice->Isr.FuncFlag == PXENV_UNDI_ISR_OUT_RECEIVE) {
// note - this code will hang on a receive interrupt in a GetStatus loop
DEBUG((EFI_D_NET," RECEIVE\n"));
SimpleNetworkDevice->InterruptStatus |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
DEBUG((EFI_D_NET, "SimpleNetworkDevice->Isr.BufferLength = %d\n", SimpleNetworkDevice->Isr.BufferLength));
DEBUG((EFI_D_NET, "SimpleNetworkDevice->Isr.FrameLength = %d\n", SimpleNetworkDevice->Isr.FrameLength));
DEBUG((EFI_D_NET, "SimpleNetworkDevice->Isr.FrameHeaderLength = %d\n", SimpleNetworkDevice->Isr.FrameHeaderLength));
DEBUG((EFI_D_NET, "SimpleNetworkDevice->Isr.Frame = %04x:%04x\n", SimpleNetworkDevice->Isr.FrameSegSel,SimpleNetworkDevice->Isr.FrameOffset));
DEBUG((EFI_D_NET, "SimpleNetworkDevice->Isr.ProtType = 0x%02x\n", SimpleNetworkDevice->Isr.BufferLength));
DEBUG((EFI_D_NET, "SimpleNetworkDevice->Isr.PktType = 0x%02x\n", SimpleNetworkDevice->Isr.BufferLength));
if (FrameReceived == TRUE) {
return EFI_SUCCESS;
}
if ((Frame == NULL) || (SimpleNetworkDevice->Isr.FrameLength > *FrameLength)) {
DEBUG((EFI_D_NET, "return EFI_BUFFER_TOO_SMALL *FrameLength = %08x\n",*FrameLength));
*FrameLength = SimpleNetworkDevice->Isr.FrameLength;
return EFI_BUFFER_TOO_SMALL;
}
*FrameLength = SimpleNetworkDevice->Isr.FrameLength;
if (FrameHeaderLength != NULL) {
*FrameHeaderLength = SimpleNetworkDevice->Isr.FrameHeaderLength;
}
if (ProtType != NULL) {
*ProtType = SimpleNetworkDevice->Isr.ProtType;
}
if (PktType != NULL) {
*PktType = SimpleNetworkDevice->Isr.PktType;
}
EfiCopyMem(Frame,(VOID *)((SimpleNetworkDevice->Isr.FrameSegSel << 4) + SimpleNetworkDevice->Isr.FrameOffset),SimpleNetworkDevice->Isr.BufferLength);
Frame = Frame + SimpleNetworkDevice->Isr.BufferLength;
if (SimpleNetworkDevice->Isr.BufferLength == SimpleNetworkDevice->Isr.FrameLength) {
FrameReceived = TRUE;
}
}
//
// There is data to process, so call until all events processed.
//
EfiZeroMem(&SimpleNetworkDevice->Isr,sizeof(PXENV_UNDI_ISR_t));
SimpleNetworkDevice->Isr.Status = INIT_PXE_STATUS;
SimpleNetworkDevice->Isr.FuncFlag = PXENV_UNDI_ISR_IN_GET_NEXT;
DEBUG((EFI_D_NET, "Isr() GET NEXT\n"));
Status = PxeUndiIsr (SimpleNetworkDevice, &SimpleNetworkDevice->Isr);
if (EFI_ERROR(Status)) {
return Status;
}
//
// Check the status code from the 16 bit UNDI ROM
//
// if (SimpleNetworkDevice->Isr.Status != PXENV_STATUS_SUCCESS) {
// return EFI_DEVICE_ERROR;
// }
}
SimpleNetworkDevice->IsrValid = FALSE;
return EFI_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////////
// Simple Network Protocol Interface Functions using 16 bit UNDI Option ROMs
/////////////////////////////////////////////////////////////////////////////////////////
//
// Start()
//
EFI_STATUS
Undi16SimpleNetworkStart (
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;
}
//
// Verify that the current state of the adapter is valid for this call.
//
switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
case EfiSimpleNetworkStopped:
break;
case EfiSimpleNetworkStarted:
case EfiSimpleNetworkInitialized:
return EFI_ALREADY_STARTED;
default:
return EFI_DEVICE_ERROR;
}
//
// The UNDI interface has been started, so update the State.
//
SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkStarted;
//
//
//
SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting = 0;
SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount = 0;
return Status;
}
//
// Stop()
//
EFI_STATUS
Undi16SimpleNetworkStop (
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;
}
//
// Verify that the current state of the adapter is valid for this call.
//
switch (SimpleNetworkDevice->SimpleNetworkMode.State) {
case EfiSimpleNetworkStarted:
break;
case EfiSimpleNetworkStopped:
return EFI_NOT_STARTED;
case EfiSimpleNetworkInitialized:
default:
return EFI_DEVICE_ERROR;
}
SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkStopped;
return Status;
}
//
// Initialize()
//
EFI_STATUS
Undi16SimpleNetworkInitialize (
IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
IN UINTN ExtraRxBufferSize OPTIONAL,
IN UINTN ExtraTxBufferSize OPTIONAL
)
{
EFI_STATUS Status;
EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
PXENV_UNDI_INITIALIZE_t Initialize;
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 EfiSimpleNetworkStarted:
break;
case EfiSimpleNetworkInitialized:
default:
return EFI_DEVICE_ERROR;
}
//
// Call 16 bit UNDI ROM to start the network interface
//
Initialize.Status = INIT_PXE_STATUS;
Initialize.ProtocolIni = 0;
Status = PxeUndiInitialize(SimpleNetworkDevice, &Initialize);
if (EFI_ERROR(Status)) {
DEBUG((EFI_D_ERROR,"ERROR : PxeUndiInitialize() - Status = %r\n",Status));
DEBUG((EFI_D_ERROR, "Initialize.Status == %xh\n", Initialize.Status));
if (Initialize.Status == PXENV_STATUS_UNDI_MEDIATEST_FAILED) {
Status = EFI_NO_MEDIA;
}
return Status;
}
//
// Check the status code from the 16 bit UNDI ROM
//
if (Initialize.Status != PXENV_STATUS_SUCCESS) {
DEBUG((EFI_D_ERROR,"ERROR : PxeUndiInitialize() - Initialize.Status = %04x\n",Initialize.Status));
return EFI_DEVICE_ERROR;
}
//
// Call 16 bit UNDI ROM to open the network interface
//
Open.Status = INIT_PXE_STATUS;
Open.OpenFlag = 0;
Open.PktFilter = Undi16GetPacketFilterSetting(SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting);
Undi16GetMCastFilters(&SimpleNetworkDevice->SimpleNetworkMode,
&Open.McastBuffer,
SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize);
Status = PxeUndiOpen(SimpleNetworkDevice, &Open);
if (EFI_ERROR(Status)) {
DEBUG((EFI_D_ERROR,"ERROR : PxeUndiOpen() - Status = %r\n",Status));
return Status;
}
//
// Check the status code from the 16 bit UNDI ROM
//
if (Open.Status != PXENV_STATUS_SUCCESS) {
DEBUG((EFI_D_ERROR,"ERROR : PxeUndiOpen() - Open.Status = %04x\n",Open.Status));
return EFI_DEVICE_ERROR;
}
//
// The UNDI interface has been initialized, so update the State.
//
SimpleNetworkDevice->SimpleNetworkMode.State = EfiSimpleNetworkInitialized;
//
// If initialize succeeds, then assume that media is present.
//
SimpleNetworkDevice->SimpleNetworkMode.MediaPresent = TRUE;
//
// Reset the recycled transmit buffer FIFO
//
SimpleNetworkDevice->TxBufferFifo.First = 0;
SimpleNetworkDevice->TxBufferFifo.Last = 0;
SimpleNetworkDevice->IsrValid = FALSE;
return Status;
}
//
// Reset()
//
EFI_STATUS
Undi16SimpleNetworkReset (
IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
IN BOOLEAN ExtendedVerification
)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?