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

📄 chip.c

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 C
📖 第 1 页 / 共 3 页
字号:
//------------------------------------------------------------------------------
//
//  Copyright (C) 2006, Freescale Semiconductor, Inc. All Rights Reserved.
//  THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
//  AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT 
//
//------------------------------------------------------------------------------
//
//  File:  chip.c
//
//  Implementation of FEC Driver
//
//  This file implements hardware related functions for FEC.
//
//-----------------------------------------------------------------------------

#include "fec.h"
#include "phys.h"
//------------------------------------------------------------------------------
// Defines
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
extern PCSP_FEC_REGS    gpFECReg;
extern CRITICAL_SECTION gFECBufCs;

//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------
FEC_MII_LIST   gMIICmds[FEC_MII_COUNT];
PFEC_MII_LIST  gMIIFree = NULL;
PFEC_MII_LIST  gMIIHead = NULL;
PFEC_MII_LIST  gMIITail = NULL;

//------------------------------------------------------------------------------
// File-local(static) Variables
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// External Functions
//------------------------------------------------------------------------------
extern BOOL BSPFECIomuxConfig( IN BOOL Enable );
extern BOOL BSPFECClockConfig( IN BOOL Enable );

//------------------------------------------------------------------------------
// Local Functions
//------------------------------------------------------------------------------

void  FECSetMII(IN PFEC_ENET_PRIVATE pFEC);

BOOL FECQueueMII(
	IN PFEC_ENET_PRIVATE pFEC,
	IN UINT RegValue,
	IN void (*OpFunc)(UINT, NDIS_HANDLE)
	);
	
void FECDoMIICmd(
	IN PFEC_ENET_PRIVATE pFEC,
	IN PFEC_PHY_CMD pCmd
	);
	
void FECGetPHYId2(
	IN UINT MIIReg,
	IN NDIS_HANDLE MiniportAdapterHandle
	);

//------------------------------------------------------------------------------
// Functions implementation
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//
// Function: FECStartXmit
//
// This function gets the transmit data and sets the transmit buffer descriptors
// for transmitting process.
//
// Parameters:
//		pEthernet
//			[in]  Specifies the driver allocated context area in which the driver
//				  maintains FEC adapter state, set up by FECInitialize.
// 
// Return value:
//		TRUE for success, FALSE for failure.
//
//------------------------------------------------------------------------------
BOOL FECStartXmit(pFEC_t pEthernet)
{
	volatile PBUFFER_DESC BufferDescPointer;
	UINT index;
	PUCHAR MemAddr;

	// Packet size of the packet
	UINT PacketSize;
	UINT CurrenSize = 0;
	PNDIS_BUFFER pNDISBuffer;
	
	// Holds virtual address of the current buffer
	PUCHAR CurrentBufAddress;
	
	// Holds the length of the current buffer of the packet
	DWORD BufferLength;
	
	PFEC_ENET_PRIVATE pFEC = &(pEthernet->FECPrivateInfo);
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +FECStartXmit\r\n")));
	
	//if(pFEC->LinkStatus == FALSE)
	//{
		// Link is down or autonegotiation is in progress
	//	return FALSE;
	//}
	
	BufferDescPointer = pFEC->CurrentTx;
	
	if(BufferDescPointer->ControlStatus & BD_ENET_TX_READY)
	{
		// Transmit buffers are full
		return FALSE;
	}
	
	// Clear all of the status flags
	BufferDescPointer->ControlStatus &= ~BD_ENET_TX_STATS; 
	
	index = BufferDescPointer - pFEC->TxBufferDescBase;
	MemAddr = pFEC->TxBuffAddr[index];
	
	// Check whether the first packet is NULL
	if(pEthernet->HeadPacket == NULL)
	{
		return FALSE;
	}
	
	// Get the length of the packet and the pointer to NDIS Buffer
	NdisQueryPacket(pEthernet->HeadPacket, NULL, NULL, &pNDISBuffer, &PacketSize);
	
	NdisQueryBuffer(pNDISBuffer, (PVOID *)&CurrentBufAddress, &BufferLength);
	
	while(pNDISBuffer)
	{
		if((BufferLength != 0) && (CurrentBufAddress != NULL))
		{
			memcpy(MemAddr, CurrentBufAddress, BufferLength);
			MemAddr += BufferLength;
			CurrenSize += BufferLength;
		}
		
		NdisGetNextBuffer(pNDISBuffer, &pNDISBuffer);
                
        if (pNDISBuffer)
		{
			NdisQueryBuffer(pNDISBuffer, (PVOID *)&CurrentBufAddress, &BufferLength);
		}
	
	}
	
	// set up the transmit buffer descriptor
	BufferDescPointer->ControlStatus |= (BD_ENET_TX_READY | BD_ENET_TX_INTR |
										 BD_ENET_TX_LAST  | BD_ENET_TX_TC);
										 
	BufferDescPointer->DataLen = (USHORT)PacketSize;
	
	// Trigger transmission start
	INSREG32BF(&gpFECReg->TDAR, FEC_TDAR_ACTIVE, FEC_TDAR_ACTIVE_ACTIVE);
	
	// If this was the last BD in the ring, start at the begining again
	if(BufferDescPointer->ControlStatus & BD_ENET_TX_WRAP)
	{
		BufferDescPointer = pFEC->TxBufferDescBase;
	}
	else
	{
		BufferDescPointer++;
	}
	
	if(BufferDescPointer == pFEC->DirtyTx)
	{
		pFEC->TxFull = TRUE;
	}
	
	pFEC->CurrentTx = (PBUFFER_DESC)BufferDescPointer;
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECStartXmit\r\n")));
	
	return TRUE;
}



//------------------------------------------------------------------------------
// MII management related functions
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//
// Function: FECSetMII
//
// This function sets the clock for the MII interface
//
// Parameters:
//		pFEC
//			[in] Pointer to a structure which contains the status and control
//				 information for the FEC controller and MII
// Return Value:
//		None.
//
//------------------------------------------------------------------------------ 
void  FECSetMII(  IN PFEC_ENET_PRIVATE pFEC  )
{
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +FECSetMII\r\n")));
	
	OUTREG32(&gpFECReg->RCR,
					CSP_BITFVAL(FEC_RCR_MAXFL, PKT_MAXBUF_SIZE)|
					CSP_BITFVAL(FEC_RCR_MIIMODE, FEC_RCR_MIIMODE_ENABLE));
					
	OUTREG32(&gpFECReg->TCR, 0);
	
	// Set MII speed to 2.5MHz
	pFEC->MIIPhySpeed = 14;
	
	OUTREG32(&gpFECReg->MSCR,
					 CSP_BITFVAL(FEC_MSCR_MIISPEED, pFEC->MIIPhySpeed));
					 
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECSetMII\r\n")));
}


//------------------------------------------------------------------------------
//
// Function: FECQueueMII
//
// This function adds a MII management command to the MII command list
//
// Parameters:
//		pFEC
//			[in] Pointer to a structure which contains the status and control
//				 information for the FEC controller and MII
//		RegValue
//			[in] The MII command which will be added to the MII command list
//				 
//		OpFunc
//          [in] An optional function which will be performed when the MII interrupt
//				 arrived.
// Return Value:
//		TRUE if the MII command has been added to the command list successfully,
//      FALSE if the command list is full.
//
//------------------------------------------------------------------------------
BOOL FECQueueMII(
	IN PFEC_ENET_PRIVATE pFEC,
	IN UINT RegValue,
	IN void (*OpFunc)(UINT, NDIS_HANDLE)
	)
{
	BOOL RetVal = TRUE;
	PFEC_MII_LIST MIIPoint;

	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +FECQueueMII\r\n")));
	
	// add PHY address to the MII command
	RegValue |= CSP_BITFVAL(FEC_MMFR_PA, pFEC->MIIPhyAddr);
	
	if((MIIPoint = gMIIFree) != NULL)
	{
		gMIIFree = MIIPoint->MIINext;
		MIIPoint->MIIRegVal = RegValue;
		MIIPoint->MIIFunction = OpFunc;
		MIIPoint->MIINext = NULL;
		
		if(gMIIHead) 
		{
			gMIITail->MIINext = MIIPoint;
			gMIITail = MIIPoint;	
		}
		else
		{
			gMIIHead = gMIITail = MIIPoint;
			OUTREG32(&gpFECReg->MMFR, RegValue);
		}
	}
	else
	{
		RetVal = FALSE;
	}
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECQueueMII\r\n")));
	
	return RetVal;
}

//------------------------------------------------------------------------------
//
// Function: FECDoMIICmd
//
// This function will call FECQueueMII to queue all the requested MII management
// commands to the sending list.
//
// Parameters:
//		pFEC
//			[in] Points to a structure which contains the status and control
//				 information for the FEC controller and MII
//
//		pCmd
//			[in] Points to a FEC_PHY_CMD array which specifies the MII management
//				 commands and the parsing functions
// Return Value:
//		None
//
//------------------------------------------------------------------------------
void FECDoMIICmd(
	IN PFEC_ENET_PRIVATE pFEC,
	IN PFEC_PHY_CMD pCmd
	)
{
	UINT i;
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +FECDoMIICmd\r\n")));
	
	if(!pCmd)
		return;
		
	for(i = 0; (pCmd + i)->MIIData != FEC_MII_END; i++ )
	{
		FECQueueMII(pFEC, (pCmd + i)->MIIData, (pCmd + i)->MIIFunct);
	}
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECDoMIICmd\r\n")));
}

//------------------------------------------------------------------------------
//
// Function: FECParseMIISr
//
// This function parses the status register data of the external MII compatible
// PHY(s).
//
// Parameters:
//		RegVal
//			[in] the status register value get from external MII compatible
//				 PHY(s)
//
//		MiniportAdapterHandle
//			[in] Specifies the handle to the driver allocated context area in
//				 which the driver maintains FEC adapter state, set up by
//				 FECInitialize
//
// Return Value:
//		None
//
//------------------------------------------------------------------------------
void FECParseMIISr(
	IN UINT RegVal,
	IN NDIS_HANDLE MiniportAdapterHandle
	)
{
	UINT Status;
	volatile UINT *s;
	
	pFEC_t pEthernet = ((pFEC_t)(MiniportAdapterHandle));
	PFEC_ENET_PRIVATE pFEC = &(pEthernet->FECPrivateInfo);
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +FECParseMIISr\r\n")));
	
	s = &(pFEC->MIIPhyStatus);
	
	Status = *s & ~(PHY_STAT_LINK | PHY_STAT_FAULT | PHY_STAT_ANC);
	
	if(RegVal & 0x0004)
		Status |= PHY_STAT_LINK;
	if(RegVal & 0x0010)
		Status |= PHY_STAT_FAULT;
	if(RegVal & 0x0020)
		Status |= PHY_STAT_ANC;
		
	*s = Status;
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECParseMIISr\r\n")));
}

//------------------------------------------------------------------------------
//
// Function: FECParseMIICr
//
// This function parses the control register data of the external MII compatible
// PHY(s).
//
// Parameters:
//		RegVal
//			[in] the control register value get from external MII compatible
//				 PHY(s)
//
//		MiniportAdapterHandle
//			[in] Specifies the handle to the driver allocated context area in
//				 which the driver maintains FEC adapter state, set up by
//				 FECInitialize
//
// Return Value:
//		None
//
//------------------------------------------------------------------------------
void FECParseMIICr(
	IN UINT RegVal,
	IN NDIS_HANDLE MiniportAdapterHandle
	)
{
	UINT Status;
	volatile UINT *s;
	
	pFEC_t pEthernet = ((pFEC_t)(MiniportAdapterHandle));
	PFEC_ENET_PRIVATE pFEC = &(pEthernet->FECPrivateInfo);
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +FECParseMIICr\r\n")));
	
	s = &(pFEC->MIIPhyStatus);
	
	Status = *s & ~(PHY_CONF_ANE | PHY_CONF_LOOP);
	
	if(RegVal & 0x1000)
		Status |= PHY_CONF_ANE;
	if(RegVal & 0x4000)
		Status |= PHY_CONF_LOOP;
		
	*s = Status;
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECParseMIICr\r\n")));	
}

//------------------------------------------------------------------------------
//
// Function: FECParseMIIAnar
//
// This function parses the Auto-Negotiation Advertisement Register data of the  
// external MII compatible PHY(s).
//
// Parameters:
//		RegVal
//			[in] the Auto-Negotiation Advertisement Register value get from 
//				 external MII compatible PHY(s)
//
//		MiniportAdapterHandle
//			[in] Specifies the handle to the driver allocated context area in
//				 which the driver maintains FEC adapter state, set up by
//				 FECInitialize
//
// Return Value:
//		None
//
//------------------------------------------------------------------------------

⌨️ 快捷键说明

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