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

📄 fec.c

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 C
📖 第 1 页 / 共 3 页
字号:
//		Returns NDIS_STATUS_PENDING if success 
//		Returns NDIS_STATUS_FAILURE if bad frame encountered
//  
//------------------------------------------------------------------------------
NDIS_STATUS FECSend(
	IN NDIS_HANDLE MiniportAdapterContext,
	IN PNDIS_PACKET Packet,
	IN UINT SendFlags
	)
{
	UINT PacketLength;
	pFEC_t pEthernet = ((pFEC_t)(MiniportAdapterContext));
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +FECSend\r\n")));
	
	NdisQueryPacket( Packet,NULL,NULL,NULL,&PacketLength);
	
	if( (PacketLength > PKT_MAXBUF_SIZE) ||(PacketLength < ETHER_HDR_SIZE))
	{
		pEthernet->TxdStatus.FramesXmitBad++;
		return NDIS_STATUS_FAILURE;
	}
	
	// Put the packet on the send queue
	EnterCriticalSection(&gFECBufCs);
	
	if(pEthernet->HeadPacket == NULL)
	{
		pEthernet->HeadPacket = Packet;
	}
	else
	{
		RESERVED(pEthernet->TailPacket)->Next = Packet;
	}
	
	RESERVED(Packet)->Next = NULL;
	pEthernet->TailPacket = Packet;
	
	LeaveCriticalSection (&gFECBufCs);
	
	if(pEthernet->TransmitInProgress == FALSE)
	{
		pEthernet->TransmitInProgress = TRUE;
		FECStartXmit(pEthernet);
	}
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECSend\r\n")));
	
	return NDIS_STATUS_PENDING;

}

//------------------------------------------------------------------------------
//
// Function: FECTransferData
// 
// This function copies the content of the received packet to a given 
// protocol-allocated packet.
// 
// Parameters:
//		Packet
//			[out] Point to a packet descriptor with chained buffers into which
//				  FECTransferData should copy the received data
//
//		BytesTransferred
//			[out] Points to a variable that FECTransferData sets to the number
//				  of bytes it  copied into the packet
//
//		MiniportAdapterContext
//			[in]  Specifies the handle to a miniport-allocated context area in 
//				  which the driver maintains FEC adapter state, set up by
//				  FECInitialize
//
//		MiniportReceiveContext
//			[in]  Specifies the context handle previously passed to 
//				  NdisMEthIndicateReceive. The miniport can examine this value
//				  to determine which recieve to copy
//
//		ByteOffset
//			[in]  Specifies the offset within the received packet at which
//				  FECTransferData should begin the copy. If the entire packet
//				  is to be copied, should be set to zero.
//
//		BytesToTransfer
//			[in]  Specifies how many bytes to copy
//
// Return Value:
//		Returns NDIS_STATUS_SUCCESS if success
//		Return NDIS_STATUS_FAILURE if not
//
//------------------------------------------------------------------------------
NDIS_STATUS
FECTransferData(
	OUT PNDIS_PACKET  Packet,
	OUT PUINT  BytesTransferred,
	IN NDIS_HANDLE MiniportAdapterContext,
	IN NDIS_HANDLE MiniportReceiveContext,
	IN UINT  ByteOffset,
	IN UINT  BytesToTransfer
	)
{
	PNDIS_BUFFER pCurrentBuffer;
	UINT   BufferLength;
	PUCHAR pBufferSource;
	PUCHAR pBufferStart;
	UINT   BytesWanted, BytesCopied, BytesLeft;
	ULONG  PacketSize;
	
	// The adapter to transfer from
	pFEC_t pEthernet = ((pFEC_t)(MiniportReceiveContext));
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +FECTransferData\r\n")));
	
	// Add the packet header onto the offset
	ByteOffset += ETHER_HDR_SIZE;
	pBufferSource = pEthernet->ReceiveBuffer + ByteOffset;
	PacketSize = pEthernet->ReceivePacketSize;
	
	if((BytesToTransfer == 0) || (ByteOffset >= PacketSize))
	{
		*BytesTransferred = 0;
		return NDIS_STATUS_FAILURE;
	}
	
	NdisQueryPacket( Packet, NULL, NULL, &pCurrentBuffer, NULL );
	NdisQueryBuffer( pCurrentBuffer, &pBufferStart, &BufferLength );
	
	*BytesTransferred = 0;
	BytesWanted = 0;
	BytesCopied = 0;
	BytesLeft = BytesToTransfer;
	
	do {
	
		if( !BufferLength )
		{
			NdisGetNextBuffer( pCurrentBuffer, &pCurrentBuffer );
			NdisQueryBuffer( pCurrentBuffer, &pBufferStart, &BufferLength );
		}
		
		if( BufferLength > BytesLeft )
		{
			BytesCopied += BytesLeft;
			BytesWanted = BytesLeft;
		}
		else
		{
			BytesCopied += BufferLength;
			BytesWanted = BufferLength;
			BufferLength = 0;
		}
		
		NdisMoveMemory( pBufferStart, pBufferSource, BytesWanted );
		pBufferStart += BytesWanted;
		pBufferSource += BytesWanted;
		BytesLeft -= BytesWanted;
		
	} while(BytesCopied < BytesToTransfer);
	
	*BytesTransferred = BytesCopied;
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECTransferData\r\n")));
	return NDIS_STATUS_SUCCESS;
}

//------------------------------------------------------------------------------
//
// Function: FECSetInformation
//
// This function is a required function that allows NDIS to request changes in
// the state information that the FEC driver maintains for particular object 
// identifiers, such as changes in multicast addresses.
// 
// Parameters:
//     MiniportAdapterContext
//             [in]  Specifies the handle to a FEC driver allocated context area
//                   in which the FEC driver maintains FEC adapter state, set up
//                   by FECInitialize function.
//
//     Oid
//             [in]  Specifies the system-defined OID_XXX code designating the 
//                   set operation the FEC driver should carry out.
//
//     InformationBuffer
//             [in]  Points to a buffer containing the OID-specific data used by
//                   FECSetInformation for the set.
//
//     InformationBufferLength
//             [in]  Specifies the number of bytes at InformationBuffer.
//
//     BytesRead
//             [out] Points to a variable that FECSetInformation sets to the number
//                   of bytes it read from the buffer at InformationBuffer.
//
//     BytesNeeded
//             [out] Points to a variable that FECSetInformation sets to the number
//                   of additional bytes it needs to satisfy the request if 
//                   InformationBufferLength is less than Oid requires.
//
// Return Value:
//     Return NDIS_STATUS_SUCCESS if the required Oid is set successfully.
//     Return NDIS_STATUS_INVALID_LENGTH if the InformationBufferLength does not 
//     match the length required by the given Oid.
//
//---------------------------------------------------------------------------------

NDIS_STATUS FECSetInformation (
	IN NDIS_HANDLE MiniportAdapterContext,
	IN NDIS_OID Oid,
	IN PVOID InformationBuffer,
	IN ULONG InformationBufferLength,
	OUT PULONG BytesRead,
	OUT PULONG BytesNeeded
	)
{
	UINT BytesLeft = InformationBufferLength;
	PUCHAR InfoBuffer = (PUCHAR)(InformationBuffer);
	
	// Variables for a particular request
	UINT OidLength;
	
	// Variables for holding the new values to be used
	ULONG LookAhead;
	ULONG Filter;

	// Status of the operation
	NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
	pFEC_t pEthernet = ((pFEC_t)(MiniportAdapterContext));
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +FECSetInformation\r\n")));
	
	// Get Oid and Length of request
	OidLength = BytesLeft;
	
	switch (Oid)
	{
		case OID_802_3_MULTICAST_LIST:
			// Verify length
			if ((OidLength % ETHER_ADDR_SIZE) != 0)
			{
				StatusToReturn = NDIS_STATUS_INVALID_DATA;
				*BytesRead = 0;
				*BytesNeeded = 0;
				break;
			}
			else
			{
				// Ensure that the multi cast list is not full yet
				if(OidLength <= (MCAST_LIST_SIZE * ETHER_ADDR_SIZE))
				{
					// Get the multicast address and update hash table
					NdisMoveMemory(pEthernet->McastList, InfoBuffer, OidLength);
					*BytesRead = OidLength;
					pEthernet->NumMulticastAddressesInUse = OidLength / ETHER_ADDR_SIZE;
					
					// clear all the content in hardware Hash Table
					ClearAllMultiCast();
					
					// Add the hash table value according to the multicast address
					for(LookAhead=0; LookAhead < pEthernet->NumMulticastAddressesInUse; LookAhead++)
					{
						AddMultiCast(&(pEthernet->McastList[LookAhead][0]));
					}
				}
				else
				{
					*BytesRead = 0;
					StatusToReturn = NDIS_STATUS_MULTICAST_FULL;
				}
			}
			break;
			
		case OID_GEN_CURRENT_PACKET_FILTER:
			// check for length
			if( OidLength != 4 )
			{
				StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
				*BytesRead = 0;
				*BytesNeeded = 0;
				break;
			}
			
			NdisMoveMemory((PUCHAR)&Filter, (PUCHAR)InfoBuffer, 4);
			
			if (Filter & (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 |
						  NDIS_PACKET_TYPE_ALL_MULTICAST
						  ))
			{
				StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
				*BytesRead = 4;
				*BytesNeeded = 0;
			}
			else
			{
				pEthernet->PacketFilter = Filter;
				
				if(Filter & NDIS_PACKET_TYPE_MULTICAST )
				{
					// clear all the content in hardware Hash Table
					ClearAllMultiCast();
					
					// Add the hash table value according to the multicast address
					for(LookAhead=0; LookAhead < pEthernet->NumMulticastAddressesInUse; LookAhead++)
					{
						AddMultiCast(&(pEthernet->McastList[LookAhead][0]));
					}
				}
				
				// TODO: how to set the FEC hardware filter? NO IDEA 
				
				StatusToReturn = NDIS_STATUS_SUCCESS;

			}
			break;
			
		case OID_GEN_CURRENT_LOOKAHEAD:
			// check for length
			if( OidLength != 4 )
			{
				StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
				*BytesRead = 0;
				*BytesNeeded = 0;
				break;
			}
			
			// Stores the new lookahead value
			NdisMoveMemory(&LookAhead, InfoBuffer, 4);
			
			if( LookAhead <= (PKT_MAXBUF_SIZE - ETHER_HDR_SIZE - PKT_CRC_SIZE) )
			{
				pEthernet->CurrentLookAhead= LookAhead;
			}
			else
			{
				StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
			}
			break;
			
		case OID_GEN_PROTOCOL_OPTIONS:
			break;
			
		default:
			*BytesRead = 0;
			*BytesNeeded = 0;
			StatusToReturn = NDIS_STATUS_INVALID_OID;
			break;
	}
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECSetInformation\r\n")));
	
	return (StatusToReturn);
}

//------------------------------------------------------------------------------
//
// Function: FECShutdown
//
// Restore the FEC adapter to its initial state when the system is shut down, 
// whether by the user or because an unrecoverable system error occurred.
//
// Parameters:
//		ShutdownContext
//			[in] Points to a context area supplied when the FECInitialize
//				 function calls NdisMRegisterAdapterShutdownHandler.
//
// Return Value:
//		None.
//
//------------------------------------------------------------------------------
void FECShutdown(
	IN PVOID ShutdownContext
	)
{
	pFEC_t pEthernet = ((pFEC_t)(ShutdownContext));
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +FECShutdown\r\n")));
	
	pEthernet->CurrentState = NdisHardwareStatusNotReady;
	
	DeleteCriticalSection (&gFECRegCs);
	DeleteCriticalSection (&gFECBufCs);
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECShutdown\r\n")));
	
	return;
}

//------------------------------------------------------------------------------
//
// Function: FECCheckForHang
//
// This function reports the link status of the FEC network adapter. Bu default,
// the NDIS library calls this function approximately every two seconds.
//
// Parameters:
//		MiniportAdapterContext
//			[in] Specifies the handle to a FEC driver allocated context area
//				 in which the FEC driver maintains FEC adapter state, set up
//				 by FECInitialize function.
//
// Return Values:
//		return TRUE if this function detects that the network adapter is not
//		operating correctly, otherwise FALSE.
//
//------------------------------------------------------------------------------
BOOLEAN FECCheckForHang(IN NDIS_HANDLE MiniportAdapterContext)
{
	pFEC_t pEthernet = ((pFEC_t)(MiniportAdapterContext));
	NDIS_MEDIA_STATE OldMediaState = pEthernet->MediaState;
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +FECCheckForHang\r\n")));
	
	if(pEthernet->MediaStateChecking == TRUE) 
	{
		// Media state is checking by the MII interrupt handler now, 
		// just return FALSE
		return FALSE;
	}
	else
	{
		// send the cmd to the external PHY to get the link status
		pEthernet->MediaStateChecking = TRUE;
		
		FECGetLinkStatus(MiniportAdapterContext);	
	}
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECCheckForHang\r\n")));
	return FALSE;
}

⌨️ 快捷键说明

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