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

📄 smsc9118.c

📁 SMSC9118网卡驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
	volatile DWORD	dwReg;

	// Enable RX 
	dwReg = Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR);
	dwReg |= MAC_CR_RXEN_;
	Lan_SetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR, dwReg);

	// Wait for at least 64uSec
	DelayUsingFreeRun(pAdapter, 64L);
}

NDIS_STATUS
SetMulticastAddressListForRev1(IN PSMSC9118_ADAPTER pAdapter)
{
	DWORD dwLinkMode;

	dwLinkMode = pAdapter->lan9118_data.dwLinkMode;
	if (dwLinkMode == LINK_10MPS_HALF)
	{
		DisableMacRxEn(pAdapter);

		Lan_SetMacRegDW(pAdapter->lan9118_data.dwLanBase, HASHL, pAdapter->ucNicMulticastRegs[0]);
		Lan_SetMacRegDW(pAdapter->lan9118_data.dwLanBase, HASHH, pAdapter->ucNicMulticastRegs[1]);

		EnableMacRxEn(pAdapter);
	}
	else if (dwLinkMode == LINK_10MPS_FULL)
	{
		DWORD	dwReg;

		// 10/FD Case
		dwReg = Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR);
		if (dwReg & MAC_CR_RXEN_)
		{
			SetRegDW(pAdapter->lan9118_data.dwLanBase, INT_STS, INT_STS_RXSTOP_INT_);
			// Enable Interrupt
			Lan_EnableInterrupt((PLAN9118_DATA)&pAdapter->lan9118_data, INT_EN_RXSTOP_INT_EN_);

			dwReg = Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR);
			dwReg &= ~MAC_CR_RXEN_;
			Lan_SetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR, dwReg);

			return (NDIS_STATUS_PENDING);
		}
		else
		{
			Lan_SetMacRegDW(pAdapter->lan9118_data.dwLanBase, HASHL, pAdapter->ucNicMulticastRegs[0]);
			Lan_SetMacRegDW(pAdapter->lan9118_data.dwLanBase, HASHH, pAdapter->ucNicMulticastRegs[1]);

			// Enable RX_EN
			Lan_SetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR, 
				Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR) | 
				MAC_CR_RXEN_);
		}
	}
	else if ((dwLinkMode == LINK_100MPS_FULL) ||
			 (dwLinkMode == LINK_100MPS_HALF))
	{
		DWORD	dwReg;

		dwReg = Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR);
		if (dwReg & MAC_CR_RXEN_)
		{
			// 100/FD/HD Case
			pAdapter->f100RxEnWorkaroundDone = 0L;
			// Initiate SWINT Interrupt 
			Lan_EnableInterrupt((PLAN9118_DATA)&pAdapter->lan9118_data, INT_EN_SW_INT_EN_);
			
			return (NDIS_STATUS_PENDING);
		}
		else
		{
			UpdateFilterAndMacReg(pAdapter);
			// Enable RX 
			EnableMacRxEn(pAdapter);
		}
	}
	else
	{
		// no link
		// nothing to do	
	}

	return NDIS_STATUS_SUCCESS;
}

/*----------------------------------------------------------------------------
	SetMulticastAddressList

*/
NDIS_STATUS
SetMulticastAddressList (IN PSMSC9118_ADAPTER pAdapter)
{
	UINT uiIndex;
	UCHAR Table;
	DWORD dwBit;
	NDIS_STATUS	Ret = NDIS_STATUS_SUCCESS;

	SMSC_TRACE0(DBG_INIT,"+SetMulticastAddressList\r\n");

	pAdapter->ucNicMulticastRegs[0] = 0UL;
	pAdapter->ucNicMulticastRegs[1] = 0UL;

	for (uiIndex = 0U; uiIndex < DEFAULT_MULTICASTLISTMAX; uiIndex++)
	{
		SMSC_TRACE6(DBG_MULTICAST,"%x-%x-%x-%x-%x-%x\r\n", pAdapter->ucAddresses[uiIndex][0], pAdapter->ucAddresses[uiIndex][1], 
														   pAdapter->ucAddresses[uiIndex][2], pAdapter->ucAddresses[uiIndex][3], 
														   pAdapter->ucAddresses[uiIndex][4], pAdapter->ucAddresses[uiIndex][5]);

		GetMulticastBit (pAdapter->ucAddresses[uiIndex], &Table, &dwBit);
		SMSC_TRACE2(DBG_MULTICAST,"Table=0x%x, dwBit=0x%x\r\n", Table, dwBit);
		pAdapter->ucNicMulticastRegs[Table] |= dwBit;
		SMSC_TRACE2(DBG_MULTICAST,"ucNicMulticastRegs[0]=0x%x, ucNicMulticastRegs[1]=0x%x\r\n", pAdapter->ucNicMulticastRegs[0], pAdapter->ucNicMulticastRegs[1]);
	}

	// workaround for 118/117/116/115 A1 (REV_ID = 0x011x0001)
	if (((pAdapter->lan9118_data.dwIdRev) & 0xFFF0FFFFUL) == 0x01100001UL)
	{
		Ret = SetMulticastAddressListForRev1(pAdapter);
	}
	else
	{
		Lan_SetMacRegDW(pAdapter->lan9118_data.dwLanBase, HASHL, pAdapter->ucNicMulticastRegs[0]);
		Lan_SetMacRegDW(pAdapter->lan9118_data.dwLanBase, HASHH, pAdapter->ucNicMulticastRegs[1]);
	}

	SMSC_TRACE2(DBG_MULTICAST,"HASHH=0x%x, HASHL=0x%x\r\n", Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, HASHH),
															Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, HASHL));
	
	SMSC_TRACE0(DBG_INIT,"-SetMulticastAddressList\r\n");
	return Ret;
}

NDIS_STATUS
SetPacketFilterForRev1(IN PSMSC9118_ADAPTER pAdapter)
{
	DWORD 	dwLinkMode;

	dwLinkMode = pAdapter->lan9118_data.dwLinkMode;
	if (dwLinkMode == LINK_10MPS_HALF)
	{
		DisableMacRxEn(pAdapter);

		Smsc9118SetMacFilter(pAdapter);

		EnableMacRxEn(pAdapter);
	}
	else if (dwLinkMode == LINK_10MPS_FULL)
	{
		DWORD	dwReg;

		// 10/FD Case
		// Disable RX 
		dwReg = Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR);
		if (dwReg & MAC_CR_RXEN_)
		{
			SetRegDW(pAdapter->lan9118_data.dwLanBase, INT_STS, INT_STS_RXSTOP_INT_);
			// Enable 
			Lan_EnableInterrupt((PLAN9118_DATA)&pAdapter->lan9118_data, INT_EN_RXSTOP_INT_EN_);
			dwReg = Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR);
			dwReg &= ~MAC_CR_RXEN_;
			Lan_SetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR, dwReg);

			return (NDIS_STATUS_PENDING);
		}
		else
		{
			Smsc9118SetMacFilter(pAdapter);
			EnableMacRxEn(pAdapter);
		}
	}
	else if ((dwLinkMode == LINK_100MPS_FULL) ||
			 (dwLinkMode == LINK_100MPS_HALF))
	{
		DWORD	dwReg;

		dwReg = Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR);
		if (dwReg & MAC_CR_RXEN_)
		{
			// 100/FD/HD Case
			pAdapter->f100RxEnWorkaroundDone = 0L;
			// Initiate SWINT Interrupt 
			Lan_EnableInterrupt((PLAN9118_DATA)&pAdapter->lan9118_data, INT_EN_SW_INT_EN_);
			
			return (NDIS_STATUS_PENDING);
		}
		else
		{
			UpdateFilterAndMacReg(pAdapter);
			// Enable RX 
			EnableMacRxEn(pAdapter);
		}
	}
	else
	{
		// no link
		// nothing to do	
	}

	return NDIS_STATUS_SUCCESS;
}

/*----------------------------------------------------------------------------
	SetPacketFilter

*/
NDIS_STATUS
SetPacketFilter(IN PSMSC9118_ADAPTER pAdapter)
{
	DWORD	dwReg;
	NDIS_STATUS	Ret = NDIS_STATUS_SUCCESS;

	SMSC_TRACE0(DBG_MULTICAST,"+SetPacketFilter\r\n");

	// workaround for 118/117/116/115 A1 (REV_ID = 0x011x0001)
	if (((pAdapter->lan9118_data.dwIdRev) & 0xFFF0FFFFUL) == 0x01100001UL)
	{
		Ret = SetPacketFilterForRev1(pAdapter);
	}
	else
	{
		dwReg = Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR);
		dwReg &= ~MAC_CR_RXEN_;
		Lan_SetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR, dwReg);
		
		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_;
		}

		if (pAdapter->ulPacketFilter & (DWORD)NDIS_PACKET_TYPE_MULTICAST)
		{
			dwReg |= MAC_CR_HPFILT_;
		}
		// FIXME
		dwReg |= MAC_CR_RXEN_;
		Lan_SetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR, dwReg);
	}

	SMSC_TRACE1(DBG_MULTICAST,"***(after) MAC_CR=0x%x\r\n", 
			Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, MAC_CR));

	SMSC_TRACE1(DBG_MULTICAST,"*** ADDRH=0x%x\r\n", 
			Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, ADDRH));
	SMSC_TRACE1(DBG_MULTICAST,"*** ADDRL=0x%x\r\n", 
			Lan_GetMacRegDW(pAdapter->lan9118_data.dwLanBase, ADDRL));

	SMSC_TRACE0(DBG_MULTICAST,"-SetPacketFilter\r\n");
	return Ret;
}


/*----------------------------------------------------------------------------
	Smsc9118SetInformation
		NDIS miniport function
*/
NDIS_STATUS
Smsc9118SetInformation (IN NDIS_HANDLE hMiniportAdapterContext, 
					   IN NDIS_OID Oid, 
					   IN PVOID pInformationBuffer,
					   IN ULONG ulInformationBufferLength, 
					   OUT PULONG pulBytesRead, 
					   OUT PULONG pulBytesNeeded)
{
	SMSC9118_ADAPTER * const pAdapter = (PSMSC9118_ADAPTER)(hMiniportAdapterContext);
	const UCHAR * const pucInfoBuffer = (PUCHAR)(pInformationBuffer);
	ULONG ulPacketFilter, ulLookAhead;
	NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
	const NDIS_PM_PACKET_PATTERN *pPattern;
	NDIS_DEVICE_POWER_STATE  PowerState;   //power management

	SMSC_TRACE1(DBG_INIT,"+Smsc9118SetInformation[0x%x]\r\n", Oid);

	switch (Oid)
	{
		case OID_802_3_MULTICAST_LIST:
			SMSC_TRACE0(DBG_MULTICAST,"  OID_802_3_MULTICAST_LIST\r\n");
			if ((ulInformationBufferLength % (DWORD)ETHER_LENGTH_OF_ADDRESS) != 0UL)
			{
				StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
				*pulBytesRead = 0UL;
				*pulBytesNeeded = 0UL;
				break;
			}
			if (sizeof(pAdapter->ucAddresses) < (UINT)ulInformationBufferLength)
			{
				StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
				*pulBytesRead = 0UL;
				*pulBytesNeeded = 0UL;
				break;
			}
			NdisZeroMemory(pAdapter->ucAddresses, DEFAULT_MULTICASTLISTMAX*ETHER_LENGTH_OF_ADDRESS);
			// Set Multicast addresses
			NdisMoveMemory (pAdapter->ucAddresses, pInformationBuffer, (UINT)ulInformationBufferLength);
			StatusToReturn = SetMulticastAddressList(pAdapter);
			break;

		case OID_GEN_CURRENT_PACKET_FILTER:
			SMSC_TRACE0(DBG_MULTICAST,"  OID_GEN_CURRENT_PACKET_FILTER\r\n");
			if (ulInformationBufferLength != 4UL)
			{
				StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
				*pulBytesRead = 0UL;
				*pulBytesNeeded = 0UL;
				break;
			}
			NdisMoveMemory (&ulPacketFilter, pucInfoBuffer, 4U);

			if (ulPacketFilter & (DWORD)(NDIS_PACKET_TYPE_SOURCE_ROUTING | NDIS_PACKET_TYPE_SMT | 
								  NDIS_PACKET_TYPE_MAC_FRAME | NDIS_PACKET_TYPE_FUNCTIONAL | 
								  NDIS_PACKET_TYPE_ALL_FUNCTIONAL | NDIS_PACKET_TYPE_GROUP))
			{
				StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
				*pulBytesRead = 4UL;
				*pulBytesNeeded = 0UL;
				RETAILMSG(1, (TEXT("Error! PacketFilter = 0x%08x\r\n"), ulPacketFilter));
				break;
			}
			pAdapter->ulPacketFilter = ulPacketFilter;
			StatusToReturn = SetPacketFilter(pAdapter);
			break;

		case OID_GEN_CURRENT_LOOKAHEAD:
			SMSC_TRACE0(DBG_INIT,"  OID_GEN_CURRENT_LOOKAHEAD\r\n");
			if (ulInformationBufferLength != 4UL)
			{
				StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
				*pulBytesRead = 0UL;
				*pulBytesNeeded = 0UL;
				break;
			}
			NdisMoveMemory (&ulLookAhead, pucInfoBuffer, 4U);
			if (ulLookAhead <= (DWORD)MAX_LOOKAHEAD) {
				pAdapter->ulMaxLookAhead = ulLookAhead;
			}
			else {
				StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
			}
			break;

		//
		//	Power Management
		//
		case OID_PNP_SET_POWER:
			SMSC_TRACE0(DBG_POWER,"  OID_PNP_SET_POWER\r\n");
			PowerState = *(PNDIS_DEVICE_POWER_STATE)pInformationBuffer;
			SetPowerState(pAdapter, PowerState);
			break;

		case OID_PNP_ADD_WAKE_UP_PATTERN:
			SMSC_TRACE0(DBG_POWER,"  OID_PNP_ADD_WAKE_UP_PATTERN\r\n");
			pPattern = (PNDIS_PM_PACKET_PATTERN)pInformationBuffer;
			SMSC_TRACE1(DBG_POWER,"MaskSize=%d\r\n", pPattern->MaskSize);
			SMSC_TRACE2(DBG_POWER,"PatternOffset=%d(0x%x)\r\n", pPattern->PatternOffset, pPattern->PatternOffset);
			SMSC_TRACE1(DBG_POWER,"PatternSize=%d\r\n", pPattern->PatternSize);
			if ((pPattern->PatternSize < 13UL) || 
				(pPattern->MaskSize < 2UL) || 
				(pPattern->MaskSize > 6UL))   //pPattern->MaskSize always <6(?)
			{
				// Pattern is too short, since 9118 start checking after MAC dst/src address.
				if (pPattern->PatternSize < 13UL) {
				   SMSC_TRACE0(DBG_POWER, "WAKEUP Pattern Error: PatternSize is smaller than 13 bytes.\r\n");
				}

				if (pPattern->MaskSize < 2UL) {
				   SMSC_TRACE0(DBG_POWER, "WAKEUP Pattern Error: MaskSize is smaller than 2 bytes.\r\n");
				}
				else if (pPattern->MaskSize > 6UL) {
				   SMSC_TRACE0(DBG_POWER, "WAKEUP Pattern Error: MaskSize is larger than 6 bytes.\r\n");
				}
				else {
				   SMSC_TRACE0(DBG_POWER, "WAKEUP Pattern Error: Error! 2 <= MaskSize <= 6\r\n");
				}
				StatusToReturn = NDIS_STATUS_NOT_ACCEPTED;
				break;
			}
			else
			{
				if ( ((pAdapter->Wuff.FilterCommands)&(FILTER3_ENABLE|FILTER2_ENABLE|FILTER1_ENABLE|FILTER0_ENABLE)) == 
					 (FILTER3_ENABLE|FILTER2_ENABLE|FILTER1_ENABLE|FILTER0_ENABLE) )
				{
					//All Wuff slots are used.
					SMSC_TRACE0(DBG_POWER,"No filter is available(all 4 filters in use).\r\n");
					StatusToReturn = NDIS_STATUS_RESOURCES;
					break;
				}
				else
				{
					//There is at least one filter available.
					if( !((pAdapter->Wuff.FilterCommands)&FILTER0_ENABLE) )
					{
						SetWakeUpFrameFilter(pAdapter, pPattern, 0UL);
						(pAdapter->Wuff.FilterCommands) |= FILTER0_ENABLE;
						(pAdapter->Wuff.FilterCommands) &= ~FILTER0_ADDR_TYPE;
					}
					else
					{
						if( !((pAdapter->Wuff.FilterCommands)&FILTER1_ENABLE) )
						{
							SetWakeUpFrameFilter(pAdapter, pPattern, 1UL);
							(pAdapter->Wuff.FilterCommands) |= FILTER1_ENABLE;
							(pAdapter->Wuff.FilterCommands) &= ~FILTER1_ADDR_TYPE;
						}
						else
						{
							if( !((pAdapter->Wuff.FilterCommands)&FILTER2_ENABLE) )
							{
								SetWakeUpFrameFilter(pAdapter, pPattern, 2UL);
								(pAdapter->Wuff.FilterCommands) |= FILTER2_ENABLE;
								(pAdapter->Wuff.FilterCommands) &= ~FILTER2_ADDR_TYPE;
							}
							else
							{
								if( !((pAdapter->Wuff.FilterCommands)&FILTER3_ENABLE) )
								{
									SetWakeUpFrameFilter(pAdapter

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -