ip4driver.c
来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C语言 代码 · 共 957 行 · 第 1/2 页
C
957 行
/*++
Copyright (c) 2005 - 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
Ip4Driver.c
Abstract:
The driver binding and service binding protocol for IP4 driver.
--*/
#include "Ip4Impl.h"
EFI_DRIVER_BINDING_PROTOCOL gIp4DriverBinding = {
Ip4DriverBindingSupported,
Ip4DriverBindingStart,
Ip4DriverBindingStop,
0x10,
NULL,
NULL
};
EFI_DRIVER_ENTRY_POINT (Ip4DriverEntryPoint)
EFI_STATUS
EFIAPI
Ip4DriverEntryPoint (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
/*++
Routine Description:
The entry point for IP4 driver which install the driver
binding and component name protocol on its image.
Arguments:
ImageHandle - The image handle of the driver
SystemTable - The system table
Returns:
EFI_SUCCESS if the driver binding and component name protocols
are successfully installed, otherwise if failed.
--*/
{
return NetLibInstallAllDriverProtocols (
ImageHandle,
SystemTable,
&gIp4DriverBinding,
ImageHandle,
&gIp4ComponentName,
NULL,
NULL
);
}
EFI_STATUS
EFIAPI
Ip4DriverBindingSupported (
IN EFI_DRIVER_BINDING_PROTOCOL * This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
)
/*++
Routine Description:
Test to see if this driver supports ControllerHandle.
Arguments:
This - Protocol instance pointer.
ControllerHandle - Handle of device to test
RemainingDevicePath - Optional parameter use to pick a specific child
device to start.
Returns:
EFI_SUCCES - This driver supports this device
EFI_ALREADY_STARTED - This driver is already running on this device
other - This driver does not support this device
--*/
{
EFI_STATUS Status;
//
// Test for the MNP service binding Protocol
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiManagedNetworkServiceBindingProtocolGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Test for the Arp service binding Protocol
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiArpServiceBindingProtocolGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
return Status;
}
STATIC
EFI_STATUS
Ip4CleanService (
IN IP4_SERVICE *IpSb
);
STATIC
EFI_STATUS
Ip4CreateService (
IN EFI_HANDLE Controller,
IN EFI_HANDLE ImageHandle,
OUT IP4_SERVICE **Service
)
/*++
Routine Description:
Create a new IP4 driver service binding protocol
Arguments:
Controller - The controller that has MNP service binding installed
ImageHandle - The IP4 driver's image handle
Service - The variable to receive the newly created IP4 service.
Returns:
EFI_OUT_OF_RESOURCES - Failed to allocate some resource
EFI_SUCCESS - A new IP4 service binding private is created.
--*/
{
IP4_SERVICE *IpSb;
EFI_STATUS Status;
ASSERT (Service != NULL);
*Service = NULL;
//
// allocate a service private data then initialize all the filed to
// empty resources, so if any thing goes wrong when allocating
// resources, Ip4CleanService can be called to clean it up.
//
IpSb = NetAllocatePool (sizeof (IP4_SERVICE));
if (IpSb == NULL) {
return EFI_OUT_OF_RESOURCES;
}
IpSb->Signature = IP4_SERVICE_SIGNATURE;
IpSb->ServiceBinding.CreateChild = Ip4ServiceBindingCreateChild;
IpSb->ServiceBinding.DestroyChild = Ip4ServiceBindingDestroyChild;
IpSb->State = IP4_SERVICE_UNSTARTED;
IpSb->InDestory = FALSE;
IpSb->NumChildren = 0;
NetListInit (&IpSb->Children);
NetListInit (&IpSb->Interfaces);
IpSb->DefaultInterface = NULL;
IpSb->DefaultRouteTable = NULL;
Ip4InitAssembleTable (&IpSb->Assemble);
IpSb->IgmpCtrl.Igmpv1QuerySeen = 0;
NetListInit (&IpSb->IgmpCtrl.Groups);
IpSb->Image = ImageHandle;
IpSb->Controller = Controller;
IpSb->MnpChildHandle = NULL;
IpSb->Mnp = NULL;
IpSb->MnpConfigData.ReceivedQueueTimeoutValue = 0;
IpSb->MnpConfigData.TransmitQueueTimeoutValue = 0;
IpSb->MnpConfigData.ProtocolTypeFilter = IP4_ETHER_PROTO;
IpSb->MnpConfigData.EnableUnicastReceive = TRUE;
IpSb->MnpConfigData.EnableMulticastReceive = TRUE;
IpSb->MnpConfigData.EnableBroadcastReceive = TRUE;
IpSb->MnpConfigData.EnablePromiscuousReceive = FALSE;
IpSb->MnpConfigData.FlushQueuesOnReset = TRUE;
IpSb->MnpConfigData.EnableReceiveTimestamps = FALSE;
IpSb->MnpConfigData.DisableBackgroundPolling = FALSE;
NetZeroMem (&IpSb->SnpMode, sizeof (EFI_SIMPLE_NETWORK_MODE));
IpSb->Timer = NULL;
IpSb->Ip4Config = NULL;
IpSb->DoneEvent = NULL;
IpSb->ReconfigEvent = NULL;
//
// Create various resources. First create the route table, timer
// event and MNP child. IGMP, interface's initialization depend
// on the MNP child.
//
IpSb->DefaultRouteTable = Ip4CreateRouteTable ();
if (IpSb->DefaultRouteTable == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_ERROR;
}
Status = gBS->CreateEvent (
EFI_EVENT_NOTIFY_SIGNAL | EFI_EVENT_TIMER,
EFI_TPL_CALLBACK,
Ip4TimerTicking,
IpSb,
&IpSb->Timer
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
Status = NetLibCreateServiceChild (
Controller,
ImageHandle,
&gEfiManagedNetworkServiceBindingProtocolGuid,
&IpSb->MnpChildHandle
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
Status = gBS->OpenProtocol (
IpSb->MnpChildHandle,
&gEfiManagedNetworkProtocolGuid,
&IpSb->Mnp,
ImageHandle,
Controller,
EFI_OPEN_PROTOCOL_BY_DRIVER
);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
Status = Ip4ServiceConfigMnp (IpSb, TRUE);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
Status = IpSb->Mnp->GetModeData (IpSb->Mnp, NULL, &IpSb->SnpMode);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
Status = Ip4InitIgmp (IpSb);
if (EFI_ERROR (Status)) {
goto ON_ERROR;
}
IpSb->DefaultInterface = Ip4CreateInterface (IpSb->Mnp, Controller, ImageHandle);
if (IpSb->DefaultInterface == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto ON_ERROR;
}
NetListInsertHead (&IpSb->Interfaces, &IpSb->DefaultInterface->Link);
IpSb->MacString = NULL;
*Service = IpSb;
return EFI_SUCCESS;
ON_ERROR:
Ip4CleanService (IpSb);
NetFreePool (IpSb);
return Status;
}
EFI_STATUS
Ip4CleanService (
IN IP4_SERVICE *IpSb
)
/*++
Routine Description:
Clean up a IP4 service binding instance. It will release all
the resource allocated by the instance. The instance may be
partly initialized, or partly destoried. If a resource is
destoried, it is marked as that in case the destory failed and
being called again later.
Arguments:
IpSb - The IP4 serviceing binding instance to clean up
Returns:
EFI_SUCCESS - The resource used by the instance are cleaned up
Others - Failed to clean up some of the resources.
--*/
{
EFI_STATUS Status;
if (IpSb->DefaultInterface != NULL) {
Status = Ip4FreeInterface (IpSb->DefaultInterface, NULL);
if (EFI_ERROR (Status)) {
return Status;
}
IpSb->DefaultInterface = NULL;
}
if (IpSb->DefaultRouteTable != NULL) {
Ip4FreeRouteTable (IpSb->DefaultRouteTable);
IpSb->DefaultRouteTable = NULL;
}
Ip4CleanAssembleTable (&IpSb->Assemble);
if (IpSb->MnpChildHandle != NULL) {
if (IpSb->Mnp) {
gBS->CloseProtocol (
IpSb->MnpChildHandle,
&gEfiManagedNetworkProtocolGuid,
IpSb->Image,
IpSb->Controller
);
IpSb->Mnp = NULL;
}
NetLibDestroyServiceChild (
IpSb->Controller,
IpSb->Image,
&gEfiManagedNetworkServiceBindingProtocolGuid,
IpSb->MnpChildHandle
);
IpSb->MnpChildHandle = NULL;
}
if (IpSb->Timer != NULL) {
gBS->SetTimer (IpSb->Timer, TimerCancel, 0);
gBS->CloseEvent (IpSb->Timer);
IpSb->Timer = NULL;
}
if (IpSb->Ip4Config != NULL) {
IpSb->Ip4Config->Stop (IpSb->Ip4Config);
gBS->CloseProtocol (
IpSb->Controller,
&gEfiIp4ConfigProtocolGuid,
IpSb->Image,
IpSb->Controller
);
gBS->CloseEvent (IpSb->DoneEvent);
gBS->CloseEvent (IpSb->ReconfigEvent);
IpSb->Ip4Config = NULL;
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
Ip4DriverBindingStart (
IN EFI_DRIVER_BINDING_PROTOCOL * This,
IN EFI_HANDLE ControllerHandle,
IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath OPTIONAL
)
/*++
Routine Description:
Start this driver on ControllerHandle.
Arguments:
This - Protocol instance pointer.
ControllerHandle - Handle of device to bind driver to
RemainingDevicePath - Optional parameter use to pick a specific child
device to start.
Returns:
EFI_SUCCES - This driver is added to ControllerHandle
EFI_ALREADY_STARTED - This driver is already running on ControllerHandle
other - This driver does not support this device
--*/
{
IP4_SERVICE *IpSb;
EFI_STATUS Status;
//
// Test for the Ip4 service binding protocol
//
Status = gBS->OpenProtocol (
ControllerHandle,
&gEfiIp4ServiceBindingProtocolGuid,
NULL,
This->DriverBindingHandle,
ControllerHandle,
EFI_OPEN_PROTOCOL_TEST_PROTOCOL
);
if (Status == EFI_SUCCESS) {
return EFI_ALREADY_STARTED;
}
Status = Ip4CreateService (ControllerHandle, This->DriverBindingHandle, &IpSb);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Install the Ip4ServiceBinding Protocol onto ControlerHandle
//
Status = gBS->InstallMultipleProtocolInterfaces (
&ControllerHandle,
&gEfiIp4ServiceBindingProtocolGuid,
&IpSb->ServiceBinding,
NULL
);
if (EFI_ERROR (Status)) {
goto FREE_SERVICE;
}
//
// ready to go: start the receiving and timer
//
Status = Ip4ReceiveFrame (IpSb->DefaultInterface, NULL, Ip4AccpetFrame, IpSb);
if (EFI_ERROR (Status)) {
goto UNINSTALL_PROTOCOL;
}
Status = gBS->SetTimer (IpSb->Timer, TimerPeriodic, TICKS_PER_SECOND);
if (EFI_ERROR (Status)) {
goto UNINSTALL_PROTOCOL;
}
//
// Initialize the IP4 ID
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?