?? smsc111.c
字號:
* Arguments:
* pAdapter - Pointer to the adapter structure.
* hConfigurationHandle - Handle passed to Smsc111Initialize.
* ConfigError - Was there an error during configuration reading.
* ConfigErrorValue - Value to log if there is an error.
*
* Return Value:
* Indicates the success or failure of the registration.
*/
#pragma NDIS_PAGEABLE_FUNCTION(Smsc111RegisterAdapter)
NDIS_STATUS
Smsc111RegisterAdapter (IN PSMSC111_ADAPTER pAdapter, IN NDIS_HANDLE hConfigurationHandle, IN BOOLEAN bConfigError, IN ULONG ulConfigErrorValue)
{
NDIS_STATUS status; // General purpose return from NDIS calls
DEBUGMSG (ZONE_INIT, (TEXT ("+CELAN: RegisterAdapter: pAdapter is 0x%x\r\n"), pAdapter));
//
// Check for a configuration error
//
if (bConfigError)
{
//
// Log Error and exit.
//
NdisWriteErrorLogEntry (pAdapter->hMiniportAdapterHandle, NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION, 1, ulConfigErrorValue);
DEBUGMSG (ZONE_INIT, (TEXT ("!CELAN: RegisterAdapter: LAN91C111Initialize had a config error %d\r\n"), ulConfigErrorValue));
DEBUGMSG (ZONE_INIT, (TEXT ("-CELAN: RegisterAdapter\r\n")));
return (NDIS_STATUS_FAILURE);
}
//
// Inform the wrapper of the physical attributes of this adapter.
//
NdisMSetAttributes (pAdapter->hMiniportAdapterHandle, (NDIS_HANDLE)pAdapter, FALSE, NdisInterfaceInternal);
//
// Initialize the card.
//
DEBUGMSG (ZONE_INIT, (TEXT (" CELAN: RegisterAdapter: Calling CardInitialize\r\n")));
if (!CardInitialize (pAdapter))
{
//
// Card seems to have failed.
//
DEBUGMSG (ZONE_INIT, (TEXT ("!CELAN: RegisterAdapter: CardInitialize -- Failed\r\n")));
NdisWriteErrorLogEntry (pAdapter->hMiniportAdapterHandle, NDIS_ERROR_CODE_ADAPTER_NOT_FOUND, 0);
status = NDIS_STATUS_ADAPTER_NOT_FOUND;
return (status);
}
DEBUGMSG (ZONE_INIT, (TEXT (" CELAN: RegisterAdapter: CardInitialize -- Success\r\n")));
//
// Initialize the receive variables.
//
pAdapter->usNicReceiveConfig = RCR_ENABLE | RCR_STRIP_CRC;
//
// Read the Ethernet address out of the EEPROM.
//
CardReadEthernetAddress (pAdapter);
//
// Now initialize the NIC.
//
pAdapter->usNicInterruptMask = IM_TX_INT | IM_RCV_INT | IM_RX_OVRN_INT | IM_EPH_INT;
//
// Link us on to the chain of adapters for this driver.
//
pAdapter->NextAdapter = gSmsc111MiniportBlock.AdapterQueue;
gSmsc111MiniportBlock.AdapterQueue = pAdapter;
//
// Setup the card based on the initialization information
//
DEBUGMSG (ZONE_INIT, (TEXT (" CELAN: RegisterAdapter CardSetup\r\n")));
if (CardSetup (pAdapter))
{
//
// Initialize the interrupt.
//
status = NdisMRegisterInterrupt (&pAdapter->Interrupt, pAdapter->hMiniportAdapterHandle, pAdapter->ucInterruptNumber, pAdapter->ucInterruptNumber, FALSE, FALSE, NdisInterruptLatched);
if (status == NDIS_STATUS_SUCCESS)
{
DEBUGMSG (ZONE_INIT, (TEXT (" CELAN: RegisterAdapter Interrupt Connected\r\n")));
// register a shutdown handler for this card
NdisMRegisterAdapterShutdownHandler (pAdapter->hMiniportAdapterHandle, pAdapter, Smsc111Shutdown);
//
// Start up the adapter.
//
CardStart (pAdapter);
//
// Initialization completed successfully.
//
DEBUGMSG (ZONE_INIT, (TEXT (" CELAN: RegisterAdapter OK\r\n")));
return (NDIS_STATUS_SUCCESS);
}
else
DEBUGMSG (ZONE_INIT, (TEXT ("!CELAN: RegisterAdapter NdisRegisterInterrupt Failed\r\n")));
NdisWriteErrorLogEntry (pAdapter->hMiniportAdapterHandle, NDIS_ERROR_CODE_INTERRUPT_CONNECT, 0);
}
//
// The NIC could not be written to.
//
NdisWriteErrorLogEntry (pAdapter->hMiniportAdapterHandle, NDIS_ERROR_CODE_ADAPTER_NOT_FOUND, 0);
DEBUGMSG (ZONE_INIT, (TEXT ("!CELAN: RegisterAdapter: CardSetup -- Failed\r\n")));
status = NDIS_STATUS_ADAPTER_NOT_FOUND;
//
// Code to unwind what has already been set up when a part of
// initialization fails, which is jumped into at various
// points based on where the failure occured. Jumping to
// a higher-numbered failure point will execute the code
// for that block and all lower-numbered ones.
//
//
// Take the Adapter out of the AdapterQueue.
//
if (gSmsc111MiniportBlock.AdapterQueue == pAdapter)
gSmsc111MiniportBlock.AdapterQueue = pAdapter->NextAdapter;
else
{
PSMSC111_ADAPTER TmpAdapter = gSmsc111MiniportBlock.AdapterQueue;
while (TmpAdapter->NextAdapter != pAdapter)
TmpAdapter = TmpAdapter->NextAdapter;
TmpAdapter->NextAdapter = TmpAdapter->NextAdapter->NextAdapter;
}
DEBUGMSG (ZONE_INIT, (TEXT ("-CELAN: RegisterAdapter\r\n")));
return (status);
}
/*
* Description:
* Smsc111Shutdown is called to shut down the adapter. Unblock any threads and terminate any loops.
*
* Arguments:
* hMiniportAdapterContext - The context value that the Miniport returned from Smsc111Initialize.
*
* Return Value:
* None.
*/
VOID
Smsc111Shutdown (IN NDIS_HANDLE hMiniportAdapterContext)
{
PSMSC111_ADAPTER pAdapter = (PSMSC111_ADAPTER)(hMiniportAdapterContext);
//
// Shut down the chip.
//
CardStop (pAdapter);
}
/*
* Description:
* Disable interrupts on the adaptor card.
*
* Arguments:
* pAdapter - Pointer to the pAdapter object.
*
* Return Value:
* None.
*/
#pragma NDIS_PAGEABLE_FUNCTION (CardBlockInterrupts)
VOID
CardBlockInterrupts (IN PSMSC111_ADAPTER pAdapter)
{
WORD wBank;
DEBUGMSG (ZONE_INTR, (TEXT ("CELAN: CardBlockInterrupt\r\n")));
wBank = ReadWord (pAdapter,BANK_SELECT);
SelectBank (pAdapter,BANK2);
WriteWord (pAdapter,INTERRUPT_REGISTER, 0);
SelectBank (pAdapter,wBank);
}
/*
* Description:
* Enable interrupts on the adaptor card.
*
* Arguments:
* pAdapter - Pointer to the pAdapter object.
*
* Return Value:
* None.
*/
#pragma NDIS_PAGEABLE_FUNCTION (CardUnblockInterrupts)
VOID
CardUnblockInterrupts (IN PSMSC111_ADAPTER pAdapter)
{
WORD wBank;
DEBUGMSG (ZONE_INTR, (TEXT ("CELAN: CardUnblockInterrupt: InterruptMask %04x\r\n"), pAdapter->usNicInterruptMask));
wBank = ReadWord (pAdapter,BANK_SELECT);
SelectBank (pAdapter,BANK2);
WriteWord (pAdapter,INTERRUPT_REGISTER, pAdapter->usNicInterruptMask);
SelectBank (pAdapter,wBank);
}
/*
* Description:
* Stops the card.
*
* Arguments:
* pAdapter - Pointer to the adapter structure.
*
* Return Value:
* None.
*/
VOID
CardStop (IN PSMSC111_ADAPTER pAdapter)
{
DEBUGMSG (ZONE_FUNCTION, (TEXT ("+CELAN: CardStop\r\n")));
SelectBank (pAdapter,BANK0);
WriteWord (pAdapter,RCR, 0);
DEBUGMSG (ZONE_FUNCTION, (TEXT ("-CELAN: CardStop\r\n")));
}
/*
* Description:
* Resets the card.
*
* Arguments:
* pAdapter - Pointer to the adapter structure.
*
* Return Value:
* TRUE if everything is OK.
*/
BOOLEAN
CardReset (IN PSMSC111_ADAPTER pAdapter)
{
WORD wRcr;
DEBUGMSG (ZONE_FUNCTION, (TEXT ("+CELAN: CardReset\r\n")));
//
// Stop the chip
//
CardStop (pAdapter);
//
// Write to and read from RCR to make sure it is there.
//
DEBUGMSG (ZONE_INIT, (TEXT ("CELAN: Reset LAN91C111\r\n")));
SelectBank (pAdapter,BANK0);
WriteWord (pAdapter,RCR, RCR_SOFTRESET);
Sleep (10);
wRcr = ReadWord (pAdapter,RCR);
if ((wRcr & RCR_SOFTRESET) != RCR_SOFTRESET)
{
DEBUGMSG (ZONE_ERROR, (TEXT ("CELAN: CardReset - RCR = 0x%x, Expected 0x%x\r\n"), wRcr, (RCR_SOFTRESET)));
return (FALSE);
}
WriteWord (pAdapter,RCR, 0);
Sleep (10);
//
// Restart the chip
//
CardSetup (pAdapter);
CardStart (pAdapter);
DEBUGMSG (ZONE_FUNCTION, (TEXT ("-CELAN: CardReset\r\n")));
return (TRUE);
}
/*
* Description:
* Initializes the card into a running state.
*
* Arguments:
* pAdapter - Pointer to the adapter structure.
*
* Return Value:
* TRUE if everything is OK.
*/
#pragma NDIS_PAGEABLE_FUNCTION(CardInitialize)
BOOLEAN
CardInitialize (IN PSMSC111_ADAPTER pAdapter)
{
UINT uiDelay;
WORD wRcr;
// PWORD pPcbRevisionRegisterBase;
// PWORD pSw1RegisterBase;
// ULONG ulSw1PhysicalRegisterBase;
// ULONG ulSw1PhysicalRegisterSize;
// USHORT usPcbRev;
// UCHAR ucSw1;
BOOL bResult = FALSE;
DEBUGMSG (ZONE_INIT, (TEXT ("+CELAN: CardInitialize\r\n")));
// NKDbgPrintfW (L"+CELAN: CardInitialize\r\n");
//
// VirtualAlloc Register Area SMSC111 register access.
// Page Aliegnment
if (pAdapter==NULL)
return FALSE;
pAdapter->pVirtualRegisterBase = (PBYTE)VirtualAlloc (0, SMSC111_REG_SIZE, MEM_RESERVE, PAGE_NOACCESS);
DEBUGMSG (ZONE_INIT, (TEXT ("CELAN: VirtualAlloc at 0x%x.\r\n"), pAdapter->pVirtualRegisterBase));
if (pAdapter->pVirtualRegisterBase==NULL)
return FALSE;
bResult= VirtualCopy ((PVOID)pAdapter->pVirtualRegisterBase, (PVOID)RegisterBase, SMSC111_REG_SIZE, PAGE_READWRITE | PAGE_NOCACHE);
//page alignment for ETHERNET_BASE.
if (bResult)
{
DEBUGMSG (ZONE_INIT, (TEXT ("CELAN: InitialCard at 0x%x.\r\n"), pAdapter->pVirtualRegisterBase));
// Reset the SMSC91C111
SelectBank (pAdapter,BANK0);
WriteWord (pAdapter,RCR, RCR_SOFTRESET);
Sleep (10);
wRcr = ReadWord (pAdapter,RCR);
if ((wRcr & RCR_SOFTRESET) != RCR_SOFTRESET)
{
DEBUGMSG (ZONE_ERROR, (TEXT ("CELAN: CardInitialize - RCR = 0x%x, Expected 0x%x\r\n"), wRcr, (RCR_SOFTRESET)));
bResult = FALSE;
}
else
{
WriteWord (pAdapter,RCR, 0);
Sleep (100);
// Initialize the control register
SelectBank (pAdapter,BANK1);
WriteWord (pAdapter,CONTROL, CTL_TE_ENABLE | CTL_LE_ENABLE);
// Reset MMU
SelectBank (pAdapter,BANK2);
WriteWord (pAdapter,MMU_CMD, MC_RESET);
Sleep(100);
for (uiDelay = 0; uiDelay < MMU_WAIT_LOOP*10; uiDelay++)
{
if (!(ReadWord (pAdapter,MMU_CMD) & MC_BUSY))
break;
}
if (uiDelay == MMU_WAIT_LOOP)
{
DEBUGMSG (ZONE_INIT, (TEXT ("-CELAN: CardInitialize: MMU reset failed., MMU_CMD = 0x%x\r\n"), ReadWord(pAdapter,MMU_CMD)));
bResult = FALSE;
}
else
{
DEBUGMSG (ZONE_INIT, (TEXT ("-CELAN: CardInitialize: Success\r\n")));
return (TRUE);
}
}
}
else
{
DEBUGMSG (ZONE_INIT, (TEXT ("CELAN: VirtualCopy ETHERNET_BASE failed.\r\n")));
bResult = FALSE;
}
if (pAdapter->pVirtualRegisterBase) {
VirtualFree ((PVOID)(pAdapter->pVirtualRegisterBase), 0, MEM_RELEASE);
pAdapter->pVirtualRegisterBase = NULL;
}
return (bResult);
}
/*
* Description:
* Reads in the Ethernet address from the SMSC91C111.
*
* Arguments:
* pAdapter - Pointer to the adapter structure.
*
* Return Value:
* None.
*/
#pragma NDIS_PAGEABLE_FUNCTION(CardReadEthernetAddress)
VOID
CardReadEthernetAddress (IN PSMSC111_ADAPTER pAdapter)
{
// Read the MAC address registers
SelectBank (pAdapter,BANK1);
pAdapter->ucPermanentAddress[0] = ReadWord(pAdapter,ADDR0) & 0xFF;
pAdapter->ucPermanentAddress[1] = ReadWord(pAdapter,ADDR0) >> 8;
pAdapter->ucPermanentAddress[2] = ReadWord(pAdapter,ADDR1) & 0xFF;
pAdapter->ucPermanentAddress[3] = ReadWord(pAdapter,ADDR1) >> 8;
pAdapter->ucPermanentAddress[4] = ReadWord(pAdapter,ADDR2) & 0xFF;
pAdapter->ucPermanentAddress[5] = ReadWord(pAdapter,ADDR2) >> 8;
#if 1 // for ROM
if(
((pAdapter->ucPermanentAddress[0] == 0) &&
(pAdapter->ucPermanentAddress[1] == 0) &&
(pAdapter->ucPermanentAddress[2] == 0) &&
(pAdapter->ucPermanentAddress[3] == 0) &&
(pAdapter->ucPermanentAddress[4] == 0) &&
(pAdapter->ucPermanentAddress[5] == 0) )
||
((pAdapter->ucPermanentAddress[0] == 0xff) &&
(pAdapter->ucPermanentAddress[1] == 0xff) &&
(pAdapter->ucPermanentAddress[2] == 0xff) &&
(pAdapter->ucPermanentAddress[3] == 0xff) &&
(pAdapter->ucPermanentAddress[4] == 0xff) &&
(pAdapter->ucPermanentAddress[5] == 0xff) ) )
{
if (pAdapter->ucPermanentAddress[0] == 0xff)
RETAILMSG(1, (TEXT("CELAN: !!Warning!! EEPROM doesn't have MAC address. \r\n")));
if ( (MAC0 == 0) && (MAC1 == 0) && (MAC2 == 0) )
{
RETAILMSG(1, (TEXT("CELAN: !!ERROR!! MAC address is not specified. \r\n")));
return; // Registry not set
}
else
{
// We do not have EEPROM, so let's set MAC address by software
// MAC address is specified in the registry
#define SWAPB(Word) ((Word<<8)&0xff00 | (Word>>8)&0x00ff)
SelectBank (pAdapter,BANK1);
WriteWord(pAdapter,ADDR0,SWAPB(MAC0));
WriteWord(pAdapter,ADDR1,SWAPB(MAC1));
WriteWord(pAdapter,ADDR2,SWAPB(MAC2));
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -