⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smsc9118.c

📁 SMSC9118网卡驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
						 (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 + -