📄 lan91c96_init.c
字号:
Function Name : AdapterVerify
Description :
Verifies if the current driver supports the chip.
This driver supports only LAN91C96/LAN91C113
Parameters :
MINIPORT_ADAPTER *Adapter - Pointer to the adapter structure
Return Value :
TRUE - Supported
FALSE - This driver doesn't support the chip.
*/
BOOLEAN AdapterVerify(MINIPORT_ADAPTER *Adapter)
{
USHORT TempStore;
ULONG IOBase;
USHORT ChipInfo;
RETAILMSG(ZONE_INIT, (TEXT("LAN91C96:==> Adapter Verify \r\n")));
IOBase = Adapter->IOBase;
//Check for the correct bank select
LAN91C96_Read( IOBase + BANK_SELECT, (USHORT *) &TempStore );
// RETAILMSG(1,(TEXT("TempStore = 0X%X"),TempStore));
if((TempStore & BANK_ID_MASK) != BANK_UPPER)
{
RETAILMSG(ZONE_INIT, (TEXT("LAN91C96:ERROR : Invalid BankSelect Constant===0x%x!\r\n"),IOBase));
RETAILMSG(ZONE_INIT, (TEXT("LAN91C96:<== Adapter Verify \r\n")));
return(FALSE);
}
//Get Chip ID and Revision.
LAN91C96_Write(IOBase + BANK_SELECT,(USHORT) 3);
LAN91C96_Read(IOBase + BANK3_REV,(USHORT *) &ChipInfo);
Adapter->ChipID = (ChipInfo & REV_CHIP_ID) >> 4;
Adapter->ChipRev = ChipInfo & REV_REV_ID;
if (Adapter->ChipID != CHIPID_LAN91C96)
{
RETAILMSG(ZONE_INIT, (TEXT("LAN91C96: ERROR : Invalid LAN Chip and Driver Combination \r\n")));
RETAILMSG(ZONE_INIT, (TEXT("LAN91C96:<== Adapter Verify \r\n")));
return (FALSE);
}
RETAILMSG(ZONE_INIT, (TEXT("LAN91C96:<== Adapter Verify \r\n")));
return TRUE;
}
/*
Function Name : AdapterReset
Description :
Issues a soft reset to the chip. And re-initializes the adapter structure variables.
Also re-establishes the link.
Parameters :
MINIPORT_ADAPTER *Adapter - Pointer to the adapter structure
Return Value :
TRUE - Reset is successful
else FALSE
*/
BOOLEAN AdapterReset(MINIPORT_ADAPTER *Adapter)
{
ULONG IOBase, Counter;
USHORT *EthAddress;
RETAILMSG(ZONE_INIT, (TEXT("LAN91C96:==> Adapter Reset %x\r\n"), Adapter->IOBase));
IOBase = Adapter->IOBase;
//Clear the card's interrupt mask register
LAN91C96_Write( IOBase+BANK_SELECT, 2 );
LAN91C96_Write( IOBase + BANK2_INT_STS, (USHORT)0 );
//Output reset to the card.
LAN91C96_Write( IOBase+BANK_SELECT, 0 );
LAN91C96_Write( IOBase + BANK0_RCR, (USHORT) RCR_RESET );
NdisStallExecution(1); //Initiated by writing bit hight and terminated by writing low.
LAN91C96_Write( IOBase + BANK0_RCR, (USHORT) 0);
//Write the MAC Address.
//If the MAC address was stored in the registry then we write it to the LAN91C96 else
//if the MAC address was from ROM then we store the value to the driver's storage
EthAddress = (PUSHORT) &Adapter->MACAddress;
LAN91C96_Write(IOBase + BANK_SELECT,(USHORT) 1);
if(((*EthAddress)|(*(EthAddress+2))|(*(EthAddress+4)))!=0)
{
LAN91C96_Write(IOBase + BANK1_IA0, *EthAddress++);
LAN91C96_Write(IOBase + BANK1_IA2, *EthAddress++);
LAN91C96_Write(IOBase + BANK1_IA4, *EthAddress);
}
else
{
LAN91C96_Read(IOBase + BANK1_IA0, EthAddress++);
LAN91C96_Read(IOBase + BANK1_IA2, EthAddress++);
LAN91C96_Read(IOBase + BANK1_IA4, EthAddress);
}
//Store the current Config register value
LAN91C96_Write(IOBase + BANK_SELECT,(USHORT) 1);
LAN91C96_Read(IOBase + BANK1_CONFIG,(PUSHORT) &Adapter->ConfigReg);
//No Wait state needed
Adapter->ConfigReg |= CFG_NO_WAIT;
LAN91C96_Write( Adapter->IOBase + BANK1_CONFIG, Adapter->ConfigReg);
//Restore Multicast Hash Table.
LAN91C96_Write(IOBase + BANK_SELECT, (USHORT) 3 );
for(Counter = 0;Counter < 8;Counter += 2)
LAN91C96_Write(IOBase + BANK3_MT01 + Counter, *(&Adapter->HashTable[Counter]));
/*
//zq add
// Output control register.
LAN91C96_Write( IOBase + BANK_SELECT, (USHORT) 1 );
Adapter->CtrlRegister = CTL_LE_EN | CTL_CR_EN | CTL_TE_EN;
LAN91C96_Write(IOBase + BANK1_CTL, Adapter->CtrlRegister);
*/
//Setup Receive control Register
Adapter->RCVAllMulticast = TRUE;
Adapter->RCVBroadcast = TRUE;
Adapter->PromiscuousMode = FALSE;
Adapter->RCR = RCR_RX_EN;
Adapter->RCR |= RCR_STRP_CRC;
LAN91C96_Write( IOBase + BANK_SELECT, (USHORT) 0);
LAN91C96_Write(IOBase + BANK0_RCR, Adapter->RCR);
//Setup Transmit Control Regiser
LAN91C96_Write( IOBase + BANK_SELECT, (USHORT) 0);
LAN91C96_Read ( IOBase + BANK0_TCR, &Adapter->TCR);
Adapter->TCR |= TCR_TX_ENA;
Adapter->TCR |= TCR_PAD_EN;
//Set the duplex mode
if (Adapter->Duplex)
Adapter->TCR |= TCR_FDSE;
LAN91C96_Write( IOBase + BANK0_TCR, Adapter->TCR);
//Clear operational flags.
Adapter->TxResPending = FALSE;
//zq add
//Initialize Queues.
// ClearPacketQue(Adapter->AckPending);
// ClearPacketQue(Adapter->AllocPending);
Adapter->AllocIntPending = FALSE;
//Clear all the statistic counter
Adapter->Stat_RxError =
Adapter->Stat_RxOK =
Adapter->Stat_RxOvrn =
Adapter->Stat_TxError =
Adapter->Stat_TxOK =
Adapter->Stat_AlignError =
Adapter->Stat_MultiColl =
Adapter->Stat_SingleColl = 0;
//If the adapter has already been initialized.
if (Adapter->State == NORMAL_STATE)
{
//Enable the interrupts !!
LAN91C96_Write(Adapter->IOBase + BANK_SELECT,(USHORT) 2);
LAN91C96_Write( Adapter->IOBase + BANK2_INT_STS,(USHORT)(ENABLED_INTS << 8));
}
ClearPacketQue(Adapter->AckPending);
ClearPacketQue(Adapter->AllocPending);
RETAILMSG(ZONE_INIT, (TEXT("LAN91C96:<== Adapter Reset %x\r\n"), Adapter->IOBase));
return TRUE;
}
/*
Function Name : BackOut
Description :
Called when the driver is unloaded. This releases all the OS resources
used by the chip and the driver.
Parameters :
MINIPORT_ADAPTER *Adapter
Return Value :
VOID
*/
void BackOut (MINIPORT_ADAPTER *Adapter)
{
ULONG IOBase;
RETAILMSG(ZONE_INIT, (TEXT("LAN91C96==> BackOut\r\n")));
RETAILMSG(ZONE_INIT, (TEXT("LAN91C96==> Releasing all LAN91C96 resources\r\n")));
IOBase = Adapter->IOBase;
DumpRegisters(Adapter);
// Release the IRQ.
if (Adapter->IsInterruptSet)
NdisMDeregisterInterrupt(&Adapter->InterruptInfo);
if (Adapter->IsPortRegistered)
NdisMDeregisterIoPortRange(Adapter->AdapterHandle,IOBase,16, (PVOID)IOBase);//Release the I/O Range.
//Release the LookAhead Buffer.
NdisFreeMemory(Adapter->LookAheadBuffer, LOOK_AHEAD_BUFFER_SIZE, 0);
//Release the adapter structure.
NdisFreeMemory(Adapter, MINIPORT_ADAPTER_SIZE, 0);
RETAILMSG(ZONE_INIT, (TEXT("LAN91C96<== BackOut\r\n")));
return;
}
/*
Function Name : DumpRegisters
Description :
This function is used for debugging. This dumps the contents of the all
the registers in the chip. This doesn't maintain the bank select status
This might affect some register values, which are sensitive to read.
Parameters :
MINIPORT_ADAPTER *Adapter - Pointer to the adapter structure
Return Value :
VOID
*/
VOID DumpRegisters (MINIPORT_ADAPTER *Adapter)
{
USHORT Bank,
Offset;
USHORT Value;
ULONG IOBase = Adapter->IOBase;
for (Bank=0; Bank <=3; Bank++) //Cycle the banks
{
LAN91C96_Write(IOBase + BANK_SELECT,Bank);
for (Offset=0; Offset <= 0xE; Offset+=2) //cycle the registers
{
LAN91C96_Read(IOBase+(ADDR_OFFSET(Offset)),(PUSHORT)&Value);
RETAILMSG(1, (TEXT("(%x,%x)=%4X\r\n"), Bank, Offset, Value));
}
}
}
/*
Function Name : DumpBuffer
Description :
This function dumps the contents of a buffer specified by the Buffer parameter of size Size.
This useful when it's required to dump the Tx/Rx packet buffers.
Parameters :
UCHAR *Buffer - Pointer to the buffer to dump
INT Size - No. bytes to dump
Return Value :
VOID
*/
VOID DumpBuffer (UCHAR *Buffer, INT Size)
{
int i;
if (Buffer[0] == 0xFF) return; //Donot Print Broadcasted packet.
RETAILMSG(ZONE_INIT, (TEXT("Dumping Packet, Size=%d"), Size));
for (i=0; i<Size; i++)
RETAILMSG(ZONE_INIT, (TEXT("%d, %x"), i,Buffer[i]));
}
void DumpChipBuffer (MINIPORT_ADAPTER *Adapter, int BufferNum)
{
ULONG IOBase = Adapter->IOBase, i;
USHORT BankSelectBak, PointerRegBak, PNRegBak;
USHORT temp;
RETAILMSG(1, (TEXT("LAN91C96 ==> Reverse Buffer Dump !!!\n")));
LAN91C96_Read (IOBase + BANK_SELECT, &BankSelectBak);
LAN91C96_Write (IOBase + BANK_SELECT, 2);LAN91C96_Read (IOBase + 6, &PointerRegBak);
LAN91C96_Write (IOBase + BANK_SELECT, 2);LAN91C96_Write(IOBase + 6, 0x6000); //AutoIncr+Read+Tx
LAN91C96_Write (IOBase + BANK_SELECT, 2);LAN91C96_Write(IOBase + 2, BufferNum); //AutoIncr+Read+Tx
for(i=0; i<256; i++)
{
LAN91C96_Read(IOBase + 8, &temp);
RETAILMSG(ZONE_INIT, (TEXT("~%04X"), (USHORT)temp));
}
LAN91C96_Write (IOBase + BANK_SELECT, 2);LAN91C96_Read (IOBase + 2, &PNRegBak);
LAN91C96_Write (IOBase + BANK_SELECT, 2);LAN91C96_Write(IOBase + 6, PointerRegBak);
LAN91C96_Write (IOBase + BANK_SELECT, BankSelectBak);
RETAILMSG(ZONE_INIT, (TEXT("LAN91C96 <== Reverse Buffer Dump !!!\n")));
}
VOID DumpMIR (MINIPORT_ADAPTER *Adapter, int misc)
{
USHORT BankSelectBak, temp;
LAN91C96_Read (Adapter->IOBase + BANK_SELECT, &BankSelectBak);
LAN91C96_Write (Adapter->IOBase + BANK_SELECT, 0);
LAN91C96_Read (Adapter->IOBase + 8, &temp);
RETAILMSG(ZONE_INIT, (TEXT("------ MIR = 0x%X, %d ------\n"), temp, misc));
LAN91C96_Write (Adapter->IOBase + BANK_SELECT, BankSelectBak);
}
///////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -