biossnp16.c
来自「Next BIOS Source code : Extensible Firmw」· C语言 代码 · 共 2,446 行 · 第 1/5 页
C
2,446 行
//
// Start() the SimpleNetwork device
//
DEBUG ((EFI_D_NET,"Start()\n"));
Status = Undi16SimpleNetworkStart (&SimpleNetworkDevice->SimpleNetwork);
if (EFI_ERROR (Status)) {
goto Done;
}
//
// GetInformation() the SimpleNetwork device
//
DEBUG ((EFI_D_NET,"GetInformation()\n"));
Status = Undi16SimpleNetworkGetInformation(&SimpleNetworkDevice->SimpleNetwork);
if (EFI_ERROR(Status)) {
goto Done;
}
//
// Build the device path for the child device
//
EfiZeroMem (&Node, sizeof(Node)) ;
Node.DevPath.Type = MESSAGING_DEVICE_PATH;
Node.DevPath.SubType = MSG_MAC_ADDR_DP;
SetDevicePathNodeLength (&Node.DevPath, sizeof(MAC_ADDR_DEVICE_PATH)) ;
EfiCopyMem(
&Node.MacAddr.MacAddress,
&SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress,
sizeof(EFI_MAC_ADDRESS)
);
SimpleNetworkDevice->DevicePath = EfiAppendDevicePathNode (
SimpleNetworkDevice->BaseDevicePath,
&Node.DevPath
);
//
// GetNicType() the SimpleNetwork device
//
DEBUG ((EFI_D_NET,"GetNicType()\n"));
Status = Undi16SimpleNetworkGetNicType(&SimpleNetworkDevice->SimpleNetwork);
if (EFI_ERROR(Status)) {
// goto Done;
}
//
// GetNdisInfo() the SimpleNetwork device
//
DEBUG ((EFI_D_NET,"GetNdisInfo()\n"));
Status = Undi16SimpleNetworkGetNdisInfo(&SimpleNetworkDevice->SimpleNetwork);
if (EFI_ERROR(Status)) {
goto Done;
}
//
// Stop() the SimpleNetwork device
//
DEBUG ((EFI_D_NET,"Stop()\n"));
Status = SimpleNetworkDevice->SimpleNetwork.Stop(&SimpleNetworkDevice->SimpleNetwork);
if (EFI_ERROR(Status)) {
goto Done;
}
//
// Print Mode information
//
DEBUG((EFI_D_NET,"Mode->State = %d\n",SimpleNetworkDevice->SimpleNetworkMode.State));
DEBUG((EFI_D_NET,"Mode->HwAddressSize = %d\n",SimpleNetworkDevice->SimpleNetworkMode.HwAddressSize));
DEBUG((EFI_D_NET,"Mode->MacAddressChangeable = %d\n",SimpleNetworkDevice->SimpleNetworkMode.MacAddressChangeable));
DEBUG((EFI_D_NET,"Mode->MultiplTxSupported = %d\n",SimpleNetworkDevice->SimpleNetworkMode.MultipleTxSupported));
DEBUG((EFI_D_NET,"Mode->NvRamSize = %d\n",SimpleNetworkDevice->SimpleNetworkMode.NvRamSize));
DEBUG((EFI_D_NET,"Mode->NvRamAccessSize = %d\n",SimpleNetworkDevice->SimpleNetworkMode.NvRamAccessSize));
DEBUG((EFI_D_NET,"Mode->ReceiveFilterSetting = %d\n",SimpleNetworkDevice->SimpleNetworkMode.ReceiveFilterSetting));
DEBUG((EFI_D_NET,"Mode->IfType = %d\n",SimpleNetworkDevice->SimpleNetworkMode.IfType));
DEBUG((EFI_D_NET,"Mode->MCastFilterCount = %d\n",SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount));
for (Index = 0; Index < SimpleNetworkDevice->SimpleNetworkMode.MCastFilterCount; Index++) {
DEBUG((EFI_D_NET," Filter[%02d] = ",Index));
for(j=0;j<16;j++) {
DEBUG((EFI_D_NET,"%02x ",SimpleNetworkDevice->SimpleNetworkMode.MCastFilter[Index].Addr[j]));
}
DEBUG((EFI_D_NET,"\n"));
}
DEBUG((EFI_D_NET,"CurrentAddress = "));
for(j=0;j<16;j++) {
DEBUG((EFI_D_NET,"%02x ",SimpleNetworkDevice->SimpleNetworkMode.CurrentAddress.Addr[j]));
}
DEBUG((EFI_D_NET,"\n"));
DEBUG((EFI_D_NET,"BroadcastAddress = "));
for(j=0;j<16;j++) {
DEBUG((EFI_D_NET,"%02x ",SimpleNetworkDevice->SimpleNetworkMode.BroadcastAddress.Addr[j]));
}
DEBUG((EFI_D_NET,"\n"));
DEBUG((EFI_D_NET,"PermanentAddress = "));
for(j=0;j<16;j++) {
DEBUG((EFI_D_NET,"%02x ",SimpleNetworkDevice->SimpleNetworkMode.PermanentAddress.Addr[j]));
}
DEBUG((EFI_D_NET,"\n"));
//
// The network device was started, information collected, and stopped.
// Install protocol interfaces for the SimpleNetwork device.
//
DEBUG ((EFI_D_NET,"Install Protocol Interfaces on network interface\n"));
Status = gBS->InstallMultipleProtocolInterfaces (
&SimpleNetworkDevice->Handle,
&gEfiSimpleNetworkProtocolGuid, &SimpleNetworkDevice->SimpleNetwork,
&gEfiNetworkInterfaceIdentifierProtocolGuid, &SimpleNetworkDevice->NII,
&gEfiDevicePathProtocolGuid, SimpleNetworkDevice->DevicePath,
NULL
);
if (EFI_ERROR (Status)) {
goto Done;
}
//
// Open PCI I/O from the newly created child handle
//
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **)&PciIo,
This->DriverBindingHandle,
SimpleNetworkDevice->Handle,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
DEBUG ((EFI_D_INIT,"UNDI16 Driver : EFI_SUCCESS\n"));
//
// Record the NIC controller to be managed onto the stack
//
if (!EFI_ERROR (Status)) {
NicInfo = EfiLibAllocateZeroPool (sizeof (MANAGED_NIC_INFO));
if (NicInfo == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Done;
}
NicInfo->Signature = MANAGED_NIC_INFO_SIGNATURE;
NicInfo->Controller = Controller;
InsertHeadList (&ManagedNicList, &NicInfo->Link);
}
Done:
if (EFI_ERROR (Status)) {
if (SimpleNetworkDevice) {
if (SimpleNetworkDevice->SimpleNetwork.WaitForPacket) {
gBS->CloseEvent (SimpleNetworkDevice->SimpleNetwork.WaitForPacket);
}
if (SimpleNetworkDevice->Event) {
gBS->CloseEvent (SimpleNetworkDevice->Event);
}
Undi16SimpleNetworkShutdown (&SimpleNetworkDevice->SimpleNetwork); //CLOSE + SHUTDOWN
Undi16SimpleNetworkStopUndi (SimpleNetworkDevice); //STOP
Undi16SimpleNetworkCleanupUndi (SimpleNetworkDevice); //CLEANUP
if (SimpleNetworkDevice->UndiLoaded) {
Undi16SimpleNetworkUnloadUndi (SimpleNetworkDevice);
}
if (SimpleNetworkDevice->Xmit) {
gBS->FreePages ( (EFI_PHYSICAL_ADDRESS)SimpleNetworkDevice->Xmit, sizeof (PXENV_UNDI_TBD_t)/ EFI_PAGE_SIZE + 1);
}
if (SimpleNetworkDevice->TxRealModeMediaHeader) {
gBS->FreePages ( (EFI_PHYSICAL_ADDRESS)SimpleNetworkDevice->TxRealModeMediaHeader, 1);
}
if (SimpleNetworkDevice->TxRealModeDataBuffer) {
gBS->FreePages ( (EFI_PHYSICAL_ADDRESS)SimpleNetworkDevice->TxRealModeDataBuffer, 1);
}
if (SimpleNetworkDevice->TxDestAddr) {
gBS->FreePages ( (EFI_PHYSICAL_ADDRESS)SimpleNetworkDevice->TxDestAddr, 1);
}
gBS->FreePool (SimpleNetworkDevice);
}
if (PciIo) {
PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationDisable,
EFI_PCI_DEVICE_ENABLE,
NULL
);
}
gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
gBS->CloseProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
Controller
);
}
return Status;
}
EFI_STATUS
BiosSnp16DriverBindingStop (
IN EFI_DRIVER_BINDING_PROTOCOL *This,
IN EFI_HANDLE Controller,
IN UINTN NumberOfChildren,
IN EFI_HANDLE *ChildHandleBuffer
)
/*++
Routine Description:
Stop.
Arguments:
(Standard DriverBinding Protocol Stop() function)
Returns:
EFI_STATUS
--*/
{
EFI_STATUS Status;
UINTN Index;
BOOLEAN AllChildrenStopped;
EFI_SIMPLE_NETWORK_PROTOCOL *SimpleNetwork;
EFI_SIMPLE_NETWORK_DEV *SimpleNetworkDevice;
EFI_PCI_IO_PROTOCOL *PciIo;
MANAGED_NIC_INFO *NicInfo;
//
// In order to unhook the interrupt chain set up by UNDI option ROM correctly,
// the NIC controllers have to be stopped in the reverse order that they are
// produced. So if the passed-in controller does not match on the top of the
// stack, we will refuse to stop it.
//
if (IsListEmpty (&ManagedNicList)) {
return EFI_DEVICE_ERROR;
}
NicInfo = CR(ManagedNicList.ForwardLink, MANAGED_NIC_INFO, Link, MANAGED_NIC_INFO_SIGNATURE);
if (Controller != NicInfo->Controller) {
return EFI_DEVICE_ERROR;
}
//
// Complete all outstanding transactions to Controller.
// Don't allow any new transaction to Controller to be started.
//
if (NumberOfChildren == 0) {
//
// Close the bus driver
//
Status = gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **)&PciIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR (Status)) {
PciIo->Attributes (
PciIo,
EfiPciIoAttributeOperationDisable,
EFI_PCI_DEVICE_ENABLE,
NULL
);
}
Status = gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
Controller
);
Status = gBS->CloseProtocol (
Controller,
&gEfiDevicePathProtocolGuid,
This->DriverBindingHandle,
Controller
);
//
// Remove the NIC controller from the stack of the NICs managed by this driver
//
if (!EFI_ERROR (Status)) {
RemoveEntryList (&NicInfo->Link);
gBS->FreePool (NicInfo);
}
return Status;
}
AllChildrenStopped = TRUE;
for (Index = NumberOfChildren; Index > 0; Index--) {
Status = gBS->OpenProtocol (
ChildHandleBuffer[Index - 1],
&gEfiSimpleNetworkProtocolGuid,
(VOID **)&SimpleNetwork,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
if (!EFI_ERROR(Status)) {
SimpleNetworkDevice = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (SimpleNetwork);
Status = gBS->CloseProtocol (
Controller,
&gEfiPciIoProtocolGuid,
This->DriverBindingHandle,
ChildHandleBuffer[Index - 1]
);
Status = gBS->UninstallMultipleProtocolInterfaces (
SimpleNetworkDevice->Handle,
&gEfiSimpleNetworkProtocolGuid, &SimpleNetworkDevice->SimpleNetwork,
&gEfiNetworkInterfaceIdentifierProtocolGuid, &SimpleNetworkDevice->NII,
&gEfiDevicePathProtocolGuid, SimpleNetworkDevice->DevicePath,
NULL
);
if (EFI_ERROR (Status)) {
gBS->OpenProtocol (
Controller,
&gEfiPciIoProtocolGuid,
(VOID **)&PciIo,
This->DriverBindingHandle,
ChildHandleBuffer[Index - 1],
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
} else {
if (SimpleNetworkDevice->SimpleNetwork.WaitForPacket) {
gBS->CloseEvent (SimpleNetworkDevice->SimpleNetwork.WaitForPacket);
}
if (SimpleNetworkDevice->Event) {
gBS->CloseEvent (SimpleNetworkDevice->Event);
}
Undi16SimpleNetworkShutdown (&SimpleNetworkDevice->SimpleNetwork); //CLOSE + SHUTDOWN
Undi16SimpleNetworkStopUndi (SimpleNetworkDevice); //STOP
Undi16SimpleNetworkCleanupUndi (SimpleNetworkDevice); //CLEANUP
if (SimpleNetworkDevice->UndiLoaded) {
Undi16SimpleNetworkUnloadUndi (SimpleNetworkDevice);
}
if (SimpleNetworkDevice->Xmit) {
gBS->FreePages ( (EFI_PHYSICAL_ADDRESS)SimpleNetworkDevice->Xmit, sizeof (PXENV_UNDI_TBD_t)/ EFI_PAGE_SIZE + 1);
}
if (SimpleNetworkDevice->TxRealModeMediaHeader) {
gBS->FreePages ( (EFI_PHYSICAL_ADDRESS)SimpleNetworkDevice->TxRealModeMediaHeader, 1);
}
if (SimpleNetworkDevice->TxRealModeDataBuffer) {
gBS->FreePages ( (EFI_PHYSICAL_ADDRESS)SimpleNetworkDevice->TxRealModeDataBuffer, 1);
}
if (SimpleNetworkDevice->TxDestAddr) {
gBS->FreePages ( (EFI_PHYSICAL_ADDRESS)SimpleNetworkDevice->TxDestAddr, 1);
}
gBS->FreePool (SimpleNetworkDevice);
}
}
if (EFI_ERROR(Status)) {
AllChildrenStopped = FALSE;
}
}
if (AllChildrenStopped == FALSE) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
//
// FIFO Support Functions
//
static
BOOLEAN
SimpleNetworkTransmitFifoFull (
EFI_SIMPLE_NETWORK_DEV_FIFO *Fifo
)
{
if (((Fifo->Last + 1) % EFI_SIMPLE_NETWORK_MAX_TX_FIFO_SIZE) == Fifo->First) {
return TRUE;
}
return FALSE;
}
//
//
//
static
BOOLEAN
SimpleNetworkTransmitFifoEmpty(
EFI_SIMPLE_NETWORK_DEV_FIFO *Fifo
)
{
if (Fifo->Last == Fifo->First) {
return TRUE;
}
return FALSE;
}
//
//
//
static
EFI_STATUS
SimpleNetworkTransmitFifoAdd(
EFI_SIMPLE_NETWORK_DEV_FIFO *Fifo,
VOID *Data
)
{
if (SimpleNetworkTransmitFifoFull(Fifo)) {
return EFI_OUT_OF_RESOURCES;
}
Fifo->Data[Fifo->Last] = Data;
Fifo->Last = (Fifo->Last + 1) % EFI_SIMPLE_NETWORK_MAX_TX_FIFO_SIZE;
return EFI_SUCCESS;
}
//
//
//
static
EFI_STATUS
SimpleNetworkTransmitFifoRemove(
EFI_SIMPLE_NETWORK_DEV_FIFO *Fifo,
VOID **Data
)
{
if (SimpleNetworkTransmitFifoEmpty(Fifo)) {
return EFI_OUT_OF_RESOURCES;
}
*Data = Fifo->Data[Fifo->First];
Fifo->First = (Fifo->First + 1) % EFI_SIMPLE_NETWORK_MAX_TX_FIFO_SIZE;
return EFI_SUCCESS;
}
//
// Maps from EFI Receive Packet Filter Settings to UNDI 16 Receive Packet Filter Settings
//
static
UINT16
Undi16GetPacketFilterSetting(
UINTN ReceiveFilterSetting
)
{
UINT16 PktFilter;
PktFilter = 0;
if (ReceiveFilterSetting & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?