📄 lan91c111_init.c
字号:
// Copyright (c) David Vescovi. All rights reserved.
// Part of Project DrumStix
// Windows Embedded Developers Interest Group (WE-DIG) community project.
// http://www.we-dig.org
/*
*
* Copyright (c) Standard MicroSystems Corporation. All Rights Reserved.
*
* LAN91C111 Driver for Windows CE .NET
*
* Revision History
*_______________________________________________________________________________
* Author Date Version Description
*_______________________________________________________________________________
* Pramod Bhardwaj 6/18/2002 0.1 Beta Release
* Pramod Bhardwaj 7/15/2002 1.0 Release
* Pramod Bhardwaj 1/22/2003 1.1 Removed some platform dependencies
* Pramod Bhardwaj 4/15/2003 2.0 Added support for alloc interrupt
*_______________________________________________________________________________
*
*Description:
* Contains all the initialization functions required for the driver.
*
*
*/
#include "LAN91C111.H"
extern NDIS_PHYSICAL_ADDRESS HighestAcceptedMax;
//extern VOID LAN91C111_MiniPortHandleInterrupt (IN NDIS_HANDLE AdapterContext);
NDIS_STATUS GetRegistrySettings(MINIPORT_ADAPTER *, NDIS_HANDLE);
BOOLEAN AdapterVerify(MINIPORT_ADAPTER *);
BOOLEAN AdapterReset(MINIPORT_ADAPTER *);
void BackOut(MINIPORT_ADAPTER *Adapter);
BOOLEAN EstablishLink(MINIPORT_ADAPTER *Adapter);
/*
Function Name : LAN91C111_MiniportInitialize
Description :
Called by the NDIS Wrapper to initialize the adapter.
0. Verify the Adapter v/s the driver
1. Create and initilize the adapter structure
2. Read and load the registry settings
3. Initialize the chip
4. Establish the link
Parameters :
PNDIS_STATUS OpenErrorStatus - Additional error status, if return value is error
PUINT MediumIndex - specifies the medium type the driver or its network adapter uses
PNDIS_MEDIUM MediumArray - Specifies an array of NdisMediumXXX values from which
MiniportInitialize selects one that its network adapter supports
or that the driver supports as an interface to higher-level drivers.
UINT MediumArraySize - Specifies the number of elements at MediumArray
NDIS_HANDLE AdapterHandle - Specifies a handle identifying the miniport抯 network adapter,
which is assigned by the NDIS library
NDIS_HANDLE ConfigurationContext - Specifies a handle used only during initialization for
calls to NdisXXX configuration and initialization functions
Return Value :
NDIS_STATUS Status
*/
NDIS_STATUS LAN91C111_MiniportInitialize(
PNDIS_STATUS OpenErrorStatus,
PUINT MediumIndex,
PNDIS_MEDIUM MediumArray,
UINT MediumArraySize,
NDIS_HANDLE AdapterHandle,
NDIS_HANDLE ConfigurationContext
)
{
NDIS_STATUS Status=NDIS_STATUS_SUCCESS;
UINT ArrayIndex;
PMINIPORT_ADAPTER Adapter;
USHORT temp;
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111 ==> MiniportInitialize \r\n")));
//Check for the supported 802.3 media
for(ArrayIndex = 0; ArrayIndex < MediumArraySize; ArrayIndex++)
if(MediumArray[ArrayIndex] == NdisMedium802_3) break;
if(ArrayIndex == MediumArraySize)
{
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111 : ERROR - No Supported Media types \r\n")));
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111 <== MiniportInitialize \r\n")));
return(NDIS_STATUS_UNSUPPORTED_MEDIA);
}
*MediumIndex = ArrayIndex;
//Allocate memory for the adapter structure
temp = MINIPORT_ADAPTER_SIZE;
Status = NdisAllocateMemory((PVOID *) &Adapter, MINIPORT_ADAPTER_SIZE, 0, HighestAcceptedMax);
if(Status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111: ERROR - No Memory for Adapter Structure!\r\n")));
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111 <== MiniPort Initialize\r\n")));
return(NDIS_STATUS_RESOURCES);
}
NdisZeroMemory(Adapter, MINIPORT_ADAPTER_SIZE); //Clean it up
Adapter->AdapterHandle = AdapterHandle;
Adapter->State = INITIALIZING_STATE;
Adapter->LookAheadBuffer = NULL;
Adapter->IsInterruptSet =
Adapter->IsPortRegistered = FALSE;
//Allocate the TX Buffer memory
Status = NdisAllocateMemory((PVOID *) &Adapter->TxBuffer,
MAX_FRAME_SIZE,
0,
HighestAcceptedMax);
if(Status != NDIS_STATUS_SUCCESS)
{
RETAILMSG(1, (TEXT("LAN91C111:ERROR : Can't Allocate Tx Buffer!\r\n")));
NdisFreeMemory(Adapter, MINIPORT_ADAPTER_SIZE, 0);
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111:<== MiniPort Initialize FAILED !!\r\n")));
return(NDIS_STATUS_RESOURCES);
}
else
{
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111:Allocated Tx Buffer Successfully!\r\n")));
}
//Get the adapter information from the registry
Status = GetRegistrySettings(Adapter, ConfigurationContext);
if(Status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111: ERROR - Configure Adapter failed!\r\n")));
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111 <== MiniPort Initialize\r\n")));
BackOut(Adapter);
return(NDIS_STATUS_FAILURE);
}
//Register the interrupt
NdisMSetAttributes(Adapter->AdapterHandle, (NDIS_HANDLE) Adapter, FALSE, NdisInterfaceInternal);
Status = NdisMRegisterInterrupt(&Adapter->InterruptInfo,
Adapter->AdapterHandle,
Adapter->InterruptLevel,
Adapter->InterruptLevel,
TRUE,
FALSE,
NdisInterruptLatched
);
if(Status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111 : ERROR - Can't Attach to Interrupt!\r\n")));
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111:<== MiniPort Initialize\r\n")));
BackOut(Adapter);
return(Status);
}
else
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111:Interrupt Registered !!! \r\n")));
Adapter->IsInterruptSet = TRUE;
//Register the IOBase address. Modify this code according to the platform
Status = NdisMRegisterIoPortRange((PVOID *) &(Adapter->IOBase),
Adapter->AdapterHandle,
Adapter->IOBase,
16);
if(Status != NDIS_STATUS_SUCCESS)
{
RETAILMSG(1, (TEXT("LAN91C9111 : ERROR - Can't Register I/O Port Range!\r\n")));
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C9111 <== MiniPort Initialize\r\n")));
BackOut(Adapter);
return(NDIS_STATUS_RESOURCES);
}
Adapter->IsPortRegistered = TRUE;
//Allocate the Adapter Interface Memory.
Status = NdisAllocateMemory((PVOID *) &Adapter->LookAheadBuffer,
LOOK_AHEAD_BUFFER_SIZE,
0,
HighestAcceptedMax);
if(Status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111:ERROR : Can't Allocate LookAhead Buffer!\r\n")));
BackOut(Adapter);
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111:<== MiniPort Initialize\r\n")));
return(NDIS_STATUS_FAILURE);
}
else
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111:Allocated LookAhead Buffer Successfully!\r\n")));
if(!AdapterVerify(Adapter))
{
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111:Adapter failed to Verify!\r\n")));
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111:<== MiniPort Initialize\r\n")));
return(NDIS_STATUS_FAILURE);
}
//Disable all interrupts until the initzing is completed
NdisRawWritePortUshort( Adapter->IOBase + BANK_SELECT, 2 );
NdisRawWritePortUshort( Adapter->IOBase + BANK2_INT_STS, 0 );
//Check for the MAC Address
//If Adapter->MACAddress != NULL then we need to write the new mac address to the LAN91C111 register
//Else read the LAN91C111 register and store the mac addr. in Adapter->MACAddress
if (Adapter->MACAddress[0] == 0 &&
Adapter->MACAddress[1] == 0 &&
Adapter->MACAddress[2] == 0 &&
Adapter->MACAddress[3] == 0 &&
Adapter->MACAddress[4] == 0 &&
Adapter->MACAddress[5] == 0 )
{
//Read the MAC address from the register
NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, 1);
NdisRawReadPortUshort(Adapter->IOBase + BANK1_IA0, &temp);
Adapter->MACAddress[1] = (UCHAR) (temp >> 8);
Adapter->MACAddress[0] = (UCHAR) (temp & 0xFF);
NdisRawReadPortUshort(Adapter->IOBase + BANK1_IA2, &temp);
Adapter->MACAddress[3] = (UCHAR) (temp >> 8);
Adapter->MACAddress[2] = (UCHAR) (temp & 0xFF);
NdisRawReadPortUshort(Adapter->IOBase + BANK1_IA4, &temp);
Adapter->MACAddress[5] = (UCHAR) (temp >> 8);
Adapter->MACAddress[4] = (UCHAR) (temp & 0xFF);
}
else
{
//Write the new MAC address to the register
NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT, 1);
temp = Adapter->MACAddress[1];
temp <<= 8;
temp |= Adapter->MACAddress[0];
NdisRawWritePortUshort(Adapter->IOBase + BANK1_IA0, temp);
temp = Adapter->MACAddress[3];
temp <<= 8;
temp |= Adapter->MACAddress[2];
NdisRawWritePortUshort(Adapter->IOBase + BANK1_IA2, temp);
temp = Adapter->MACAddress[5];
temp <<= 8;
temp |= Adapter->MACAddress[4];
NdisRawWritePortUshort(Adapter->IOBase + BANK1_IA4, temp);
}
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111: MAC Address - %02X-%02X-%02X-%02X-%02X-%02X\r\n"),
Adapter->MACAddress[0],
Adapter->MACAddress[1],
Adapter->MACAddress[2],
Adapter->MACAddress[3],
Adapter->MACAddress[4],
Adapter->MACAddress[5]
));
//Reset the card
if(!AdapterReset(Adapter))
{
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111: ERROR Can't Reset the Adapter!\r\n")));
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111:<== MiniPort Initialize\r\n")));
BackOut(Adapter);
return(NDIS_STATUS_FAILURE);
}
//Enable the interrupts !!
NdisRawWritePortUshort(Adapter->IOBase + BANK_SELECT,(USHORT) 2);
NdisRawWritePortUshort( Adapter->IOBase + BANK2_INT_STS,(USHORT)(ENABLED_INTS << 8));
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111 <== MiniportInitialize \r\n")));
//Ready
Adapter->State = NORMAL_STATE;
return NDIS_STATUS_SUCCESS;
}
/*
Function Name : GetRegistrySettings
Description :
Reads the registry values, and loads them into the adapter structure
Parameters :
MINIPORT_ADAPTER *Adapter - Pointer to the adapter structure
NDIS_HANDLE ConfigurationContext - Context handler, from the NDIS wrapper
Return Value :
NDIS_STATUS Status
*/
NDIS_STATUS GetRegistrySettings(MINIPORT_ADAPTER *Adapter,
NDIS_HANDLE ConfigurationContext)
{
NDIS_STATUS Status;
NDIS_HANDLE ConfigurationHandle;
PNDIS_CONFIGURATION_PARAMETER ConfigurationParameter;
UCHAR * NewNetworkAddress=NULL;
UINT NewNetworkAddressLength;
NDIS_STRING BusTypeString = NDIS_STRING_CONST("BusType");
NDIS_STRING BusNumberString = NDIS_STRING_CONST("BusNumber");
NDIS_STRING DuplexString = NDIS_STRING_CONST("DUPLEX");
NDIS_STRING FullDupString = NDIS_STRING_CONST("FULL");
NDIS_STRING HalfDupString = NDIS_STRING_CONST("HALF");
NDIS_STRING SpeedString = NDIS_STRING_CONST("SPEED");
NDIS_STRING Speed100String = NDIS_STRING_CONST("100");
NDIS_STRING Speed10String = NDIS_STRING_CONST("10");
NDIS_STRING AutoNegString = NDIS_STRING_CONST("AUTO-NEGOTIATION");
NDIS_STRING DefDupString = NDIS_STRING_CONST("DEFAULT");
NDIS_STRING IOBase = NDIS_STRING_CONST("IoBaseAddress");
NDIS_STRING Interrupt = NDIS_STRING_CONST("InterruptNumber");
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111 ==> GetRegistrySettings \r\n")));
//Set up the default values
Adapter->InterruptVector =
Adapter->InterruptLevel = DEFAULT_IRQ;
Adapter->IOBase = DEFAULT_IO_BASE;
Adapter->LookAhead = MAX_LOOKAHEAD_SIZE;
Adapter->Speed = SPEED100;
Adapter->Auto_Negotiation = TRUE;
Adapter->LinkStatus = MEDIA_DISCONNECTED;
Adapter->MACAddress[0] =
Adapter->MACAddress[1] =
Adapter->MACAddress[2] =
Adapter->MACAddress[3] =
Adapter->MACAddress[4] =
Adapter->MACAddress[5] = 0;
//Open the Registry tree for this adapter.
NdisOpenConfiguration((PNDIS_STATUS) &Status,(PNDIS_HANDLE) &ConfigurationHandle,ConfigurationContext);
if(Status != NDIS_STATUS_SUCCESS)
{
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111 : ERROR - No information for adapter!\r\n")));
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111 <== Configure Adapter\r\n")));
return(NDIS_STATUS_FAILURE);
}
//Get configured bus type value from registry,
NdisReadConfiguration((PNDIS_STATUS) &Status,
&ConfigurationParameter,
ConfigurationHandle,
(PNDIS_STRING) &BusTypeString,
NdisParameterInteger);
if(Status == NDIS_STATUS_SUCCESS)
{
Adapter->BusType = (USHORT) ConfigurationParameter->ParameterData.IntegerData;
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111:BusType = 0x%x\r\n"), Adapter->BusType));
}
else
{
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111 : ERROR - BusType not in Registry!\r\n")));
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111 <== Configure Adapter\r\n")));
NdisCloseConfiguration(ConfigurationHandle);
return(NDIS_STATUS_FAILURE);
}
//Get bus number value from registry.
NdisReadConfiguration((PNDIS_STATUS) &Status,
&ConfigurationParameter,
ConfigurationHandle,
(PNDIS_STRING) &BusNumberString,
NdisParameterInteger);
if(Status == NDIS_STATUS_SUCCESS)
{
Adapter->BusNumber = (USHORT) ConfigurationParameter->ParameterData.IntegerData;
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111:BusNumber = 0x%x\r\n"), Adapter->BusNumber));
}
else
{
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111: ERROR - BusNumber not in Registry!\r\n")));
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111<== Configure Adapter\r\n")));
NdisCloseConfiguration(ConfigurationHandle);
return(NDIS_STATUS_FAILURE);
}
//If both Duplex AND Speed are selected, in the registry, then Auto_Negotiation is false
//If either of speed or duplex is default or AutoNeg then Auto_Negotiation is turned on !!
Adapter->Duplex = DEFAULT_VALUE;
NdisReadConfiguration((PNDIS_STATUS) &Status,
&ConfigurationParameter,
ConfigurationHandle,
(PNDIS_STRING) &DuplexString,
NdisParameterString);
if(Status == NDIS_STATUS_SUCCESS)
{
if( NdisEqualString( (PNDIS_STRING) &ConfigurationParameter->ParameterData.StringData,(PNDIS_STRING) &AutoNegString,TRUE ) )
{
DEBUGMSG(ZONE_INIT, (TEXT("LAN91C111:Config is Auto-Negotiation\r\n")));
Adapter->Duplex = AUTO_NEGOTIATION;
}
else
if( NdisEqualString( (PNDIS_STRING) &ConfigurationParameter->ParameterData.StringData,(PNDIS_STRING) &DefDupString, TRUE ) )
{
DEBUGMSG(ZONE_INIT, (TEXT("Config is Default\r\n")));
Adapter->Duplex = DEFAULT_VALUE;
}
else
if( NdisEqualString( (PNDIS_STRING) &ConfigurationParameter->ParameterData.StringData,(PNDIS_STRING) &FullDupString,TRUE ) )
{
DEBUGMSG(ZONE_INIT, (TEXT("Config is Full Duplex\r\n")));
Adapter->Duplex = FULL_DUPLEX;
}
else
if( NdisEqualString( (PNDIS_STRING) &ConfigurationParameter->ParameterData.StringData,(PNDIS_STRING) &HalfDupString,TRUE ) )
{
DEBUGMSG(ZONE_INIT, (TEXT("Config is Half Duplex\r\n")));
Adapter->Duplex = HALF_DUPLEX;
}
}
Adapter->Speed = DEFAULT_VALUE;
NdisReadConfiguration((PNDIS_STATUS) &Status,
&ConfigurationParameter,
ConfigurationHandle,
(PNDIS_STRING) &SpeedString,
NdisParameterString);
if(Status == NDIS_STATUS_SUCCESS)
{
if( NdisEqualString( (PNDIS_STRING) &ConfigurationParameter->ParameterData.StringData,(PNDIS_STRING) &AutoNegString,TRUE ) )
{
DEBUGMSG(ZONE_INIT, (TEXT("Config is Auto-Negotiation\r\n")));
Adapter->Speed = AUTO_NEGOTIATION;
}
else
if( NdisEqualString( (PNDIS_STRING) &ConfigurationParameter->ParameterData.StringData,(PNDIS_STRING) &DefDupString, TRUE ) )
{
DEBUGMSG(ZONE_INIT, (TEXT("Config is Default\r\n")));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -