📄 smsc9118.c
字号:
(NDIS_HANDLE)pAdapter,
0U,
(DWORD)NDIS_ATTRIBUTE_BUS_MASTER,
NdisInterfaceInternal);
// Link us on to the chain of adapters for this driver.
pAdapter->NextAdapter = gSmsc9118MiniportBlock.AdapterQueue;
gSmsc9118MiniportBlock.AdapterQueue = pAdapter;
SMSC_TRACE1(DBG_INIT,"ucInterruptNumber(before)=0x%x\r\n", pAdapter->ucInterruptNumber);
status = NdisMRegisterInterrupt (&(pAdapter->Interrupt),
pAdapter->hMiniportAdapterHandle,
(UINT)pAdapter->ucInterruptNumber,
(UINT)pAdapter->ucInterruptNumber,
(BOOLEAN)TRUE,
(BOOLEAN)TRUE,
NdisInterruptLatched);
if (status == NDIS_STATUS_SUCCESS)
{
SMSC_TRACE0(DBG_INIT," Interrupt Connected\r\n");
}
else
{
SMSC_TRACE0(DBG_INIT," NdisRegisterInterrupt Failed\r\n");
}
if (gSmsc9118MiniportBlock.AdapterQueue == pAdapter) {
gSmsc9118MiniportBlock.AdapterQueue = pAdapter->NextAdapter;
}
else
{
PSMSC9118_ADAPTER TmpAdapter = gSmsc9118MiniportBlock.AdapterQueue;
while (TmpAdapter->NextAdapter != pAdapter) {
TmpAdapter = TmpAdapter->NextAdapter;
}
TmpAdapter->NextAdapter = TmpAdapter->NextAdapter->NextAdapter;
}
SMSC_TRACE0(DBG_INIT,"-RegisterAdapter\r\n");
return (status);
}
/*----------------------------------------------------------------------------
ChipIdentify
*/
BOOLEAN ChipIdentify (IN PSMSC9118_ADAPTER pAdapter)
{
DWORD dwValue;
SMSC_TRACE0(DBG_INIT,"+ChipIdentify\r\n");
if (pAdapter==NULL) {
return (BOOLEAN)FALSE;
}
// Check Chip ID
// Start with 32bit Mode
PlatformSetBusWidth(32UL);
dwValue = AdapterGetCSR(BYTE_TEST);
if (dwValue != 0x87654321UL)
{
// Try with 16bit mode
PlatformSetBusWidth(16UL);
dwValue = AdapterGetCSR(BYTE_TEST);
if (dwValue != 0x87654321UL)
{
SMSC_WARNING0("Error! Can not determine 16bit or 32bit mode.\r\n");
RETAILMSG(1, (TEXT("BYTE_TEST = 0x%08x\r\n"), dwValue));
return (BOOLEAN)FALSE;
}
else
{
RETAILMSG(1, (TEXT("16Bit Mode\r\n")));
}
}
else
{
RETAILMSG(1, (TEXT("32Bit Mode\r\n")));
}
if (!Lan_Initialize(&(pAdapter->lan9118_data), pAdapter->lan9118_data.dwLanBase))
{
SMSC_TRACE0(DBG_INIT,"Lan_Initialize failed.\r\n");
return (BOOLEAN)FALSE;
}
switch ((pAdapter->lan9118_data.dwIdRev)&0xFFFF0000UL)
{
case 0x118A0000UL:
RETAILMSG(1, (TEXT("Lan9218 identified. ID_REV = 0x%08lX\r\n"), (pAdapter->lan9118_data.dwIdRev)));
break;
case 0x117A0000UL:
RETAILMSG(1, (TEXT("Lan9217 identified. ID_REV = 0x%08lX\r\n"), (pAdapter->lan9118_data.dwIdRev)));
break;
case 0x116A0000UL:
RETAILMSG(1, (TEXT("Lan9216 identified. ID_REV = 0x%08lX\r\n"), (pAdapter->lan9118_data.dwIdRev)));
break;
case 0x115A0000UL:
RETAILMSG(1, (TEXT("Lan9215 identified. ID_REV = 0x%08lX\r\n"), (pAdapter->lan9118_data.dwIdRev)));
break;
case 0x01180000UL:
RETAILMSG(1, (TEXT("Lan9118 identified. ID_REV = 0x%08lX\r\n"), (pAdapter->lan9118_data.dwIdRev)));
break;
case 0x01170000UL:
RETAILMSG(1, (TEXT("Lan9117 identified. ID_REV = 0x%08lX\r\n"), (pAdapter->lan9118_data.dwIdRev)));
break;
case 0x01160000UL:
RETAILMSG(1, (TEXT("Lan9116 identified. ID_REV = 0x%08lX\r\n"), (pAdapter->lan9118_data.dwIdRev)));
break;
case 0x01150000UL:
RETAILMSG(1, (TEXT("Lan9115 identified. ID_REV = 0x%08lX\r\n"), (pAdapter->lan9118_data.dwIdRev)));
break;
case 0x01120000UL:
RETAILMSG(1, (TEXT("Lan9112 identified. ID_REV = 0x%08lX\r\n"), (pAdapter->lan9118_data.dwIdRev)));
break;
default:
SMSC_WARNING1("Can not Identify LAN9118. (ID_REV = 0x%08x)\r\n", pAdapter->lan9118_data.dwIdRev);
return (BOOLEAN)FALSE;
}
PlatformSetBusTiming(pAdapter->lan9118_data.dwIdRev);
SMSC_TRACE0(DBG_INIT,"-ChipIdentify\r\n");
return (BOOLEAN)TRUE;
}
/*----------------------------------------------------------------------------
ChipSetup
*/
BOOLEAN ChipSetup(IN PSMSC9118_ADAPTER pAdapter)
{
const DWORD dwLanBase = pAdapter->lan9118_data.dwLanBase;
DWORD dwOldGpioCfg;
DWORD dwADDRL, dwADDRH;
SMSC_TRACE0(DBG_INIT,"+ChipSetup\r\n");
Lan_InitializeInterrupts(&(pAdapter->lan9118_data), INT_DEAS);
if (!Lan_InitializePhy(&(pAdapter->lan9118_data), pAdapter->PhyAddress))
{
SMSC_TRACE0(DBG_INIT,"Lan_InitializePhy failed.\r\n");
SMSC_TRACE0(DBG_INIT,"-ChipSetup\r\n");
return (BOOLEAN)FALSE;
}
Lan_InitializeTx(&(pAdapter->lan9118_data));
if (pAdapter->fRxDMAMode)
{
#if (CACHE_LINE_BYTES==32UL)
Lan_InitializeRx(&(pAdapter->lan9118_data), 0x80000200UL, 0UL); //DMA
#elif (CACHE_LINE_BYTES==16UL)
Lan_InitializeRx(&(pAdapter->lan9118_data), 0x40000200UL, 0UL); //DMA
#else
#error "CACHE_LINE_BYTES should be defined."
#endif
}
else
{
Lan_InitializeRx(&(pAdapter->lan9118_data), 0x00000200UL, 0UL); // PIO with 2-byte offset
}
// Mac Initialize
if (pAdapter->fSwFlowControlEnabled == (BOOLEAN)TRUE)
{
EnableSwFlowControlFD(pAdapter);
}
else
{
SMSC_TRACE0(DBG_FLOW,"Flow control disabled.\r\n");
}
#ifdef USE_GPIO
// Enable GPIOs, RX_DV and TX_EN
dwOldGpioCfg = GetRegDW(dwLanBase, GPIO_CFG);
dwOldGpioCfg &= ~0x00700000UL;
// Enable GPIO3 & GPIO4
dwOldGpioCfg |= 0x00100000UL;
// Set GPIO0~2 Output
dwOldGpioCfg |= 0x00000700UL;
// Clear GPIO0~2
dwOldGpioCfg &= 0xFFFFFFF8UL;
SetRegDW(dwLanBase, GPIO_CFG, dwOldGpioCfg);
#else
dwOldGpioCfg = GPIO_CFG_LED3_EN_ | GPIO_CFG_LED2_EN_ |
GPIO_CFG_LED1_EN_ |
GPIO_CFG_GPIODIR2_ | GPIO_CFG_GPIODIR1_ |
GPIO_CFG_GPIODIR0_;
SetRegDW(dwLanBase, GPIO_CFG, dwOldGpioCfg);
#endif
//Save GPIO_CFG register
dwOldGpioCfg = GetRegDW(dwLanBase, GPIO_CFG);
//Configure EEPROM instead of GPIO use
SetRegDW(dwLanBase, GPIO_CFG, dwOldGpioCfg & ~GPIO_CFG_EEPR_EN_);
//Check automatic load
SMSC_TRACE1(DBG_EEPROM,"E2P_CMD=0x%x\r\n", GetRegDW(dwLanBase, E2P_CMD));
if (GetRegDW(dwLanBase, E2P_CMD) & E2P_CMD_E2P_PROG_DONE_)
{
//MAC address is successfully loaded from EEPROM.
SMSC_TRACE0(DBG_EEPROM,"MAC address from EEPROM is loaded.\r\n");
dwADDRL = Lan_GetMacRegDW(dwLanBase, ADDRL);
dwADDRH = Lan_GetMacRegDW(dwLanBase, ADDRH);
SMSC_TRACE2(DBG_EEPROM,"ADDRH=0x%x ADDRL=0x%x\r\n", dwADDRH, dwADDRL);
// Save the MAC address.
pAdapter->ucStationAddress[0] = LOBYTE(LOWORD(dwADDRL));
pAdapter->ucStationAddress[1] = HIBYTE(LOWORD(dwADDRL));
pAdapter->ucStationAddress[2] = LOBYTE(HIWORD(dwADDRL));
pAdapter->ucStationAddress[3] = HIBYTE(HIWORD(dwADDRL));
pAdapter->ucStationAddress[4] = LOBYTE(LOWORD(dwADDRH));
pAdapter->ucStationAddress[5] = HIBYTE(LOWORD(dwADDRH));
SMSC_TRACE6(DBG_EEPROM,"ucStationAddress=%x %x %x %x %x %x\r\n",
pAdapter->ucStationAddress[0], pAdapter->ucStationAddress[1],
pAdapter->ucStationAddress[2], pAdapter->ucStationAddress[3],
pAdapter->ucStationAddress[4], pAdapter->ucStationAddress[5] );
}
else
{
// Set the MAC address
Lan_SetMacAddress(&(pAdapter->lan9118_data), 0x00000070UL, 0x110F8000UL);
// Save the MAC address.
pAdapter->ucStationAddress[0] = (BYTE)0x00;
pAdapter->ucStationAddress[1] = (BYTE)0x80;
pAdapter->ucStationAddress[2] = (BYTE)0x0F;
pAdapter->ucStationAddress[3] = (BYTE)0x11;
pAdapter->ucStationAddress[4] = (BYTE)0x70;
pAdapter->ucStationAddress[5] = (BYTE)0x00;
}
//Restore GPIO_CFG register
SetRegDW(dwLanBase, GPIO_CFG, dwOldGpioCfg);
SMSC_TRACE0(DBG_INIT,"-ChipSetup\r\n");
return (BOOLEAN)TRUE;
}
typedef struct _SHOW_REG {
WCHAR wszName[20];
DWORD dwOffset;
} SHOW_REG;
static const SHOW_REG sysCsr[] = {
{ L"ID_REV", ID_REV },
{ L"INT_CFG", INT_CFG },
{ L"INT_STS", INT_STS },
{ L"INT_EN", INT_EN },
{ L"DMA_CFG", DMA_CFG },
{ L"BYTE_TEST", BYTE_TEST },
{ L"FIFO_INT", FIFO_INT },
{ L"RX_CFG", RX_CFG },
{ L"TX_CFG", TX_CFG },
{ L"HW_CFG", HW_CFG },
{ L"RX_DP_CTRL", RX_DP_CTL },
{ L"RX_FIFO_INF", RX_FIFO_INF },
{ L"TX_FIFO_INF", TX_FIFO_INF },
{ L"PMT_CTRL", PMT_CTRL },
{ L"GPIO_CFG", GPIO_CFG },
{ L"GPT_CFG", GPT_CFG },
{ L"GPT_CNT", GPT_CNT },
{ L"FPGA_REV", FPGA_REV },
{ L"ENDIAN", ENDIAN },
{ L"FREE_RUN", FREE_RUN },
{ L"RX_DROP", RX_DROP },
{ L"MAC_CSR_CMD", MAC_CSR_CMD },
{ L"MAC_CSR_DATA", MAC_CSR_DATA},
{ L"AFC_CFG", AFC_CFG },
{ L"E2P_CMD", E2P_CMD },
{ L"E2P_DATA", E2P_DATA },
{ L"TEST_REG_A", TEST_REG_A }
};
static const SHOW_REG macCsr[] = {
{ L"MAC_CR", MAC_CR },
{ L"MAC_ADDRH", ADDRH },
{ L"MAC_ADDRL", ADDRL },
{ L"MAC_HASHH", HASHH },
{ L"MAC_HASHL", HASHL },
{ L"MAC_MII_ACC", MII_ACC },
{ L"MAC_MII_DATA", MII_DATA },
{ L"MAC_FLOW", FLOW },
{ L"MAC_VLAN1", VLAN1 },
{ L"MAC_VLAN2", VLAN2 },
{ L"MAC_WUFF", WUFF },
{ L"MAC_WUCSR", WUCSR }
};
static const SHOW_REG phyCsr[] = {
{ L"PHY_BCR", PHY_BCR },
{ L"PHY_BSR", PHY_BSR },
{ L"PHY_ID_1", PHY_ID_1 },
{ L"PHY_ID_2", PHY_ID_2 },
{ L"PHY_ANEG_ADV", PHY_ANEG_ADV},
{ L"PHY_ANEG_LPA", PHY_ANEG_LPA},
{ L"PHY_ANEG_EXP", 6UL },
{ L"PHY_SI_REV", 16UL },
{ L"PHY_MODE_CTRL_STS", PHY_MODE_CTRL_STS },
{ L"PHY_SPECIAL_MODE", 18UL },
{ L"PHY_TSTCNTL", 20UL },
{ L"PHY_TSTREAD1", 21UL },
{ L"PHY_TSTREAD1", 22UL },
{ L"PHY_TSTWRITE", 23UL },
{ L"PHY_CONTROL", PHY_CS_IND },
{ L"PHY_SITC", 28UL },
{ L"PHY_INT_SRC", PHY_INT_SRC },
{ L"PHY_INT_MASK", PHY_INT_MASK },
{ L"PHY_SPECIAL", PHY_SPECIAL },
};
static void DumpSIMRegs(const SMSC9118_ADAPTER * const pAdapter)
{
UINT i;
RETAILMSG(1, (TEXT("Dump 9118 Slave Interface Module Registers\r\n")));
for (i=0U;i<(sizeof(sysCsr)/sizeof(SHOW_REG));i++) {
RETAILMSG(1, (TEXT("%20s = 0x%08x\r\n"),
sysCsr[i].wszName,
GetRegDW(pAdapter->lan9118_data.dwLanBase, sysCsr[i].dwOffset)));
}
}
static void DumpMACRegs(const SMSC9118_ADAPTER * const pAdapter)
{
UINT i;
RETAILMSG(1, (TEXT("Dump 9118 MAC Registers\r\n")));
for (i=0U;i<(sizeof(macCsr)/sizeof(SHOW_REG));i++) {
RETAILMSG(1, (TEXT("%20s = 0x%08x\r\n"),
macCsr[i].wszName,
Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, macCsr[i].dwOffset)));
}
}
static void DumpPHYRegs(const SMSC9118_ADAPTER * const pAdapter)
{
UINT i;
RETAILMSG(1, (TEXT("Dump 9118 PHY Registers\r\n")));
for (i=0U;i<(sizeof(phyCsr)/sizeof(SHOW_REG));i++) {
RETAILMSG(1, (TEXT("%20s = 0x%04x\r\n"),
phyCsr[i].wszName,
AdapterReadPhy(phyCsr[i].dwOffset)));
}
}
static void DumpAllRegs(const SMSC9118_ADAPTER * const pAdapter)
{
RETAILMSG(1, (TEXT("Dump All 9118 Registers\r\n")));
DumpSIMRegs(pAdapter);
DumpMACRegs(pAdapter);
DumpPHYRegs(pAdapter);
}
#ifdef TRACE_BUFFER
void DumpStatus(PSMSC9118_ADAPTER pAdapter)
{
DWORD dwRdPtr, dwWrPtr;
RETAILMSG(1, (TEXT("dwRxNumIndicate = %d\r\n"), dwRxNumIndicate));
RETAILMSG(1, (TEXT("TxReported = %d, TxSent = %d, TxPend = %d\r\n"), dwTxReported, dwTxSent, dwTxPend));
RETAILMSG(1, (TEXT("%d are in the Defered Queue\r\n"), QUEUE_COUNT(&pAdapter->TxDeferedPkt)));
RETAILMSG(1, (TEXT("Total Rx Pkt = %d, RxPktToFull = %d, RxPktToEmpty = %d, RxPktFromFull = %d, RxPktFromEmpty = %d, RxDiscard = %d\r\n"),
dwRxTotalPkt, dwRxPktToFull, dwRxPktToEmpty, dwRxPktFromFull, dwRxPktFromEmpty, dwRxDiscard));
dwRdPtr = pAdapter->EmptyPkt.dwRdPtr;
dwWrPtr = pAdapter->EmptyPkt.dwWrPtr;
RETAILMSG(1, (TEXT("RxPkt In EmptyQueue = %d\r\n"), (dwWrPtr >= dwRdPtr) ? (dwWrPtr - dwRdPtr) : (MAX_RXPACKETS_IN_QUEUE+1 - (dwRdPtr - dwWrPtr))));
RETAILMSG(1, (TEXT("pAdapter->EmptyPkt.dwRdPtr = %d, pAdapter->EmptyPkt.dwWrPtr = %d\r\n"), pAdapter->EmptyPkt.dwRdPtr, pAdapter->EmptyPkt.dwWrPtr));
dwRdPtr = pAdapter->FullPkt.dwRdPtr;
dwWrPtr = pAdapter->FullPkt.dwWrPtr;
RETAILMSG(1, (TEXT("RxPkt In FullQueue = %d\r\n"), (dwWrPtr >= dwRdPtr) ? (dwWrPtr - dwRdPtr) : (MAX_RXPACKETS_IN_QUEUE+1 - (dwRdPtr - dwWrPtr))));
RETAILMSG(1, (TEXT("pAdapter->FullPkt.dwRdPtr = %d, pAdapter->FullPkt.dwWrPtr = %d\r\n"), pAdapter->FullPkt.dwRdPtr, pAdapter->FullPkt.dwWrPtr));
}
#endif
DWORD LinkIndicate(PSMSC9118_ADAPTER pAdapter)
{
DWORD dwLinkStatus;
dwLinkStatus = Lan_GetLinkMode(&pAdapter->lan9118_data);
if (dwLinkStatus != pAdapter->lan9118_data.dwLinkMode) {
if (dwLinkStatus != LINK_NO_LINK)
{
NdisMIndicateStatus(pAdapter->hMiniportAdapterHandle,
NDIS_STATUS_MEDIA_CONNECT, (PVOID)0, 0U);
NdisMIndicateStatusComplete(pAdapter->hMiniportAdapterHandle);
}
else
{
NdisMIndicateStatus(pAdapter->hMiniportAdapterHandle,
NDIS_STATUS_MEDIA_DISCONNECT, (PVOID)0, 0U);
NdisMIndicateStatusComplete(pAdapter->hMiniportAdapterHandle);
}
pAdapter->lan9118_data.dwLinkMode = dwLinkStatus;
}
return dwLinkStatus;
}
static void Smsc9118SetMacFilter(CPCSMSC9118_ADAPTER pAdapter)
{
const DWORD dwLanBase = pAdapter->lan9118_data.dwLanBase;
DWORD dwReg;
dwReg = Lan_GetMacRegDW(dwLanBase, MAC_CR);
dwReg &= (~(MAC_CR_MCPAS_ | MAC_CR_PRMS_ | MAC_CR_INVFILT_ | MAC_CR_HFILT_ | MAC_CR_HPFILT_ | MAC_CR_BCAST_));
if (pAdapter->ulPacketFilter & (DWORD)NDIS_PACKET_TYPE_ALL_MULTICAST)
{
dwReg |= MAC_CR_MCPAS_;
}
if (pAdapter->ulPacketFilter & (DWORD)NDIS_PACKET_TYPE_PROMISCUOUS)
{
dwReg |= MAC_CR_PRMS_;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -