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

📄 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 页
字号:
	
	pFEC->DirtyTx = pFEC->CurrentTx = pFEC->TxBufferDescBase;
	pFEC->CurrentRx = pFEC->RxBufferDescBase;
	
	// allocate receive buffers and initialize the receive buffer descriptors
	BufferDescPointer = pFEC->RxBufferDescBase;
	
	MemAddr = (PUCHAR)HalAllocateCommonBuffer(
							&Adapter,
							FEC_RX_RING_SIZE * FEC_ENET_RX_FRSIZE,
							&MemPhysicalBase,
							FALSE);
							
	if(MemAddr == NULL)
	{
		DEBUGMSG(ZONE_ERROR, (TEXT("FECEnetInit: Allocate DMA memory for receive buffers failed\r\n")));
		return FALSE;
	}
	else
	{
		pFEC->RxBufferBase = (PVOID)MemAddr;
	}
							
	for(i = 0; i < FEC_RX_RING_SIZE; i++)
	{
		BufferDescPointer->ControlStatus = BD_ENET_RX_EMPTY;
		BufferDescPointer->BufferAddr = (ULONG)MemPhysicalBase.QuadPart + i*FEC_ENET_RX_FRSIZE;
		
		pFEC->RxBuffAddr[BufferDescPointer - pFEC->RxBufferDescBase] = MemAddr + i*FEC_ENET_RX_FRSIZE;
		
		BufferDescPointer++;
	}
	
	// set the last buffer to wrap 
	BufferDescPointer--;
	BufferDescPointer->ControlStatus |= BD_SC_WRAP;
	
	// allocate transmit buffers and initialize the transmit buffer descriptors
	BufferDescPointer = pFEC->TxBufferDescBase;
	
	MemAddr = (PUCHAR)HalAllocateCommonBuffer(
							&Adapter,
							FEC_TX_RING_SIZE * FEC_ENET_TX_FRSIZE,
							&MemPhysicalBase,
							FALSE);
	if(MemAddr == NULL)
	{
		DEBUGMSG(ZONE_ERROR, (TEXT("FECEnetInit: Allocate DMA memory for transmit buffers failed\r\n")));
		return FALSE;
	}
	else
	{
		pFEC->TxBufferBase = (PVOID)MemAddr;
	}						
	
	for(i = 0; i < FEC_TX_RING_SIZE; i++)
	{
		BufferDescPointer->ControlStatus = 0;
		BufferDescPointer->BufferAddr = (ULONG)MemPhysicalBase.QuadPart + i*FEC_ENET_TX_FRSIZE;
		
		pFEC->TxBuffAddr[BufferDescPointer - pFEC->TxBufferDescBase] = MemAddr + i*FEC_ENET_TX_FRSIZE;
		
		BufferDescPointer++;
	}
	
	// set the last buffer to wrap
	BufferDescPointer--;
	BufferDescPointer->ControlStatus |= BD_SC_WRAP;
	
	// issue a reset to the FEC hardware
	INSREG32BF(&gpFECReg->ECR, FEC_ECR_RESET, FEC_ECR_RESET_RESET);
	
	// wait for the hareware reset to complete
	while(EXTREG32BF(&gpFECReg->ECR, FEC_ECR_RESET));
	
	// set the receive and transmit BDs ring base to 
	// hardware registers(ERDSR & ETDSR)
	OUTREG32(&gpFECReg->ERDSR, (ULONG)pFEC->RingPhysicalBase.QuadPart);
	OUTREG32(&gpFECReg->ETDSR, 
			(ULONG)pFEC->RingPhysicalBase.QuadPart + FEC_RX_RING_SIZE*sizeof(BUFFER_DESC));
			
	// set other hardware registers
	OUTREG32(&gpFECReg->EIR, FEC_EIR_CLEARALL_MASK);

#if 0
	OUTREG32(&gpFECReg->EIMR,
					CSP_BITFVAL(FEC_EIMR_TXF, FEC_EIMR_TXF_UNMASK) |
					CSP_BITFVAL(FEC_EIMR_RXF, FEC_EIMR_RXF_UNMASK) |
					CSP_BITFVAL(FEC_EIMR_MII, FEC_EIMR_MII_UNMASK));
#endif
				
	OUTREG32(&gpFECReg->IAUR, 0);
	OUTREG32(&gpFECReg->IALR, 0);
	OUTREG32(&gpFECReg->GAUR, 0);
	OUTREG32(&gpFECReg->GALR, 0);
	
	OUTREG32(&gpFECReg->EMRBR, PKT_MAXBLR_SIZE);
	
	// enable the FEC
	INSREG32BF(&gpFECReg->ECR, FEC_ECR_ETHEREN, FEC_ECR_ETHEREN_ENABLE);
	
	INSREG32BF(&gpFECReg->RDAR, FEC_RDAR_ACTIVE, FEC_RDAR_ACTIVE_ACTIVE);
	
	// Set the station address for the FEC Adapter
	OUTREG32(&gpFECReg->PALR, pEthernet->FecMacAddress[3] |
							  pEthernet->FecMacAddress[2]<<8 |
							  pEthernet->FecMacAddress[1]<<16 |
							  pEthernet->FecMacAddress[0]<<24);
							  
	OUTREG32(&gpFECReg->PAUR, pEthernet->FecMacAddress[5]<<16 |
							  pEthernet->FecMacAddress[4]<<24);
	
	for(i = 0; i < FEC_MII_COUNT-1; i++)
	{
		gMIICmds[i].MIINext = &gMIICmds[i+1];
	}
	
	gMIIFree = gMIICmds;
	
	// setup MII interface
	FECSetMII(pFEC);
	
	// Queue up command to detect the PHY and initialize the remainder of 
	// the interface
	pFEC->TxFull = FALSE;
	pFEC->MIIPhyIdDone = FALSE;
	pFEC->MIIPhyAddr = 0;
	pFEC->MIISeqDone = FALSE;
	pFEC->LinkStatus = FALSE;
	
	pFEC->MIIPhy = NULL;
	
	FECQueueMII( pFEC, MII_READ_COMMAND(MII_REG_PHYIR1), FECGetPHYId );
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECEnetInit\r\n")));
	
	return TRUE;
}

//------------------------------------------------------------------------------
//
// Function: FECEnetDeinit
//
// This function Deinitialize the FEC hardware. It will free the DMA buffers and
// disable the GPIO and CLK for FEC.
//
// Parameters:
//		pEthernet
//			[in] the FEC driver context area allocated in function FECInitialize
//
// Return Value:
//		None.
//
//------------------------------------------------------------------------------
void FECEnetDeinit(pFEC_t pEthernet)
{
	PHYSICAL_ADDRESS	MemPhysicalBase;
	PFEC_ENET_PRIVATE pFEC = &(pEthernet->FECPrivateInfo);
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +FECEnetDeinit\r\n")));
	
	MemPhysicalBase.QuadPart = 0;
	
	// Free DMA buffers allocated(Note: only virtual address is needed)
	HalFreeCommonBuffer(NULL, 0, MemPhysicalBase, pFEC->RingBase, FALSE);
	HalFreeCommonBuffer(NULL, 0, MemPhysicalBase, pFEC->RxBufferBase, FALSE);
	HalFreeCommonBuffer(NULL, 0, MemPhysicalBase, pFEC->TxBufferBase, FALSE);
	
	// disable GPIO and CLK for FEC
	BSPFECIomuxConfig( FALSE );
	BSPFECClockConfig( FALSE );
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECEnetDeinit\r\n")));	
}

//------------------------------------------------------------------------------
//
// Function: FECEnetAutoNego
//
// This function issues the auto-negotiation sequences to the external PHY device
//
// Parameters:
//		pEthernet
//			[in] the FEC driver context area allocated in function FECInitialize
//
// Return value
//		None
//
//------------------------------------------------------------------------------
void FECEnetAutoNego(pFEC_t pEthernet)
{
	PFEC_ENET_PRIVATE pFEC = &(pEthernet->FECPrivateInfo);
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +FECEnetAutoNego\r\n")));
	
	// Wait for MII interrupt to set to TURE
	while(pFEC->MIIPhyIdDone != TRUE);
		// Sleep(10);
		
	if(pFEC->MIIPhy)
	{
		// Set to auto-negotiation mode and restart the
		// auto-negotiation process
		FECDoMIICmd(pFEC, pFEC->MIIPhy->PhyActint);
		FECDoMIICmd(pFEC, pFEC->MIIPhy->PhyConfig);
		FECDoMIICmd(pFEC, PHYCmdCfg);
		
		// wait for the auto-negotiation process to complete
		// while(pFEC->MIISeqDone != TRUE);
			//Sleep(10);
	}
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECEnetAutoNego\r\n")));
}

//------------------------------------------------------------------------------
//
// Function: FECEnetReset
//
// This function is called to restart the FEC hardware. Linking status change
// or switching between half and full duplex mode will cause this function to
// be called.
//
// Parameters:
//		MiniportAdapterHandle
//			[in] Specifies the handle to the driver allocated context area in 
//				 which the driver maintains FEC adapter state, set up by
//				 FECInitialize
//
//		DuplexMode
//			[in] TRUE for full duplex mode, FALSE for half duplex mode
//
// Return Value:
//		None
//
//------------------------------------------------------------------------------
void FECEnetReset(
	IN NDIS_HANDLE MiniportAdapterHandle,
	IN BOOL DuplexMode
	)
{
	volatile PBUFFER_DESC BufferDescPointer;
	UINT i;
	
	pFEC_t pEthernet = ((pFEC_t)(MiniportAdapterHandle));
	PFEC_ENET_PRIVATE pFEC = &(pEthernet->FECPrivateInfo);
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +FECEnetReset\r\n")));
	
	// Issues a hardware reset, we should wait for this
	INSREG32BF(&gpFECReg->ECR, FEC_ECR_RESET, FEC_ECR_RESET_RESET);
	
	while(EXTREG32BF(&gpFECReg->ECR, FEC_ECR_RESET));
	
	// Enable RxF, TxF and MII interrupts
	OUTREG32(&gpFECReg->EIMR,
					CSP_BITFVAL(FEC_EIMR_TXF, FEC_EIMR_TXF_UNMASK) |
					CSP_BITFVAL(FEC_EIMR_RXF, FEC_EIMR_RXF_UNMASK) |
					CSP_BITFVAL(FEC_EIMR_MII, FEC_EIMR_MII_UNMASK));
					
	// Clear all pending interrupts
	OUTREG32(&gpFECReg->EIR, FEC_EIR_CLEARALL_MASK);
	
	// Set the station MAC address
	//FECSetAddr(MiniportAdapterHandle);
	
	// Reset all multicast hashtable and individual hashtable
	// NIDS library will restore this by calling 
	// FECSetInformation() function
	OUTREG32(&gpFECReg->IAUR, 0);
	OUTREG32(&gpFECReg->IALR, 0);
	OUTREG32(&gpFECReg->GAUR, 0);
	OUTREG32(&gpFECReg->GALR, 0);
	
	// Set maximum receive buffer size, the size must be aligned with
	// 16 bytes
	OUTREG32(&gpFECReg->EMRBR, PKT_MAXBLR_SIZE);
	
	// Set receive and transmit descriptor base
	OUTREG32(&gpFECReg->ERDSR, (ULONG)pFEC->RingPhysicalBase.QuadPart);
	OUTREG32(&gpFECReg->ETDSR,
			(ULONG)pFEC->RingPhysicalBase.QuadPart + FEC_RX_RING_SIZE*sizeof(BUFFER_DESC));
			
	pFEC->DirtyTx = pFEC->CurrentTx = pFEC->TxBufferDescBase;
	pFEC->CurrentRx = pFEC->RxBufferDescBase;
	
	// Initialize the receive buffer descriptors
	BufferDescPointer = pFEC->RxBufferDescBase;
	
	for(i = 0; i < FEC_RX_RING_SIZE; i++)
	{
		BufferDescPointer->ControlStatus = BD_ENET_RX_EMPTY;
		BufferDescPointer++;
	}
	
	BufferDescPointer--;
	BufferDescPointer->ControlStatus |= BD_SC_WRAP;
	
	
	// Initialize the transmit buffer descriptor
	BufferDescPointer = pFEC->TxBufferDescBase;
	
	for(i = 0; i < FEC_TX_RING_SIZE; i++)
	{
		BufferDescPointer->ControlStatus = 0;
		BufferDescPointer++;
	}
	
	BufferDescPointer--;
	BufferDescPointer->ControlStatus |= BD_SC_WRAP;
	
	// Enable MII mode and set the Duplex mode
	if(DuplexMode)
	{
		// MII mode enable and FD(Full Duplex) enable 
		OUTREG32(&gpFECReg->RCR,
					CSP_BITFVAL(FEC_RCR_MAXFL, PKT_MAXBUF_SIZE)|
					CSP_BITFVAL(FEC_RCR_MIIMODE, FEC_RCR_MIIMODE_ENABLE));
					
		OUTREG32(&gpFECReg->TCR,
					CSP_BITFVAL(FEC_TCR_FDEN, FEC_TCR_FDEN_ENABLE)); 
	}
	else
	{
		// MII mode enable and FD disable
		OUTREG32(&gpFECReg->RCR,
					CSP_BITFVAL(FEC_RCR_MAXFL, PKT_MAXBUF_SIZE)|
					CSP_BITFVAL(FEC_RCR_MIIMODE, FEC_RCR_MIIMODE_ENABLE)|
					CSP_BITFVAL(FEC_RCR_DRT, FEC_RCR_DRT_ENABLE));
					
		OUTREG32(&gpFECReg->TCR, 0);
	}
	
	pFEC->FullDuplex = DuplexMode;
	
	// Set MII speed
	OUTREG32(&gpFECReg->MSCR,
					 CSP_BITFVAL(FEC_MSCR_MIISPEED, pFEC->MIIPhySpeed));
					 
	// Finally, enable the fec and enable receive/transmit processing
	INSREG32BF(&gpFECReg->ECR, FEC_ECR_ETHEREN, FEC_ECR_ETHEREN_ENABLE);
	
	INSREG32BF(&gpFECReg->RDAR, FEC_RDAR_ACTIVE, FEC_RDAR_ACTIVE_ACTIVE);
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -FECEnetReset\r\n")));
	
	return;	 
}

//------------------------------------------------------------------------------
//
// Function: CalculateHashValue
//
// This function calculates the 6-bit Hash value for multicasting.
//
// Parameters:
//      pAddr
//        [in] pointer to a ethernet address
//
// Returns:
//      Returns the calculated 6-bit Hash value.
//
//------------------------------------------------------------------------------
UCHAR CalculateHashValue(UCHAR *pAddr)
{
	ULONG CRC;
    UCHAR HashValue = 0;
    UCHAR AddrByte;
    int byte, bit;

    DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +CalculateHashValue\r\n")));
    
    // calculate CRC32 value of MAC address
    CRC = CRC_PRIME;
    
    for(byte=0; byte < ETHER_ADDR_SIZE; byte++)
    {
    	AddrByte = *pAddr++;
    	
    	for(bit = 0; bit < 8; bit++, AddrByte >>= 1)
    	{
    		CRC = (CRC >> 1) ^
    				(((CRC ^ AddrByte) & 1) ? CRC_POLYNOMIAL : 0);
    	}
    }
    
    // only upper 6 bits (HASH_BITS) are used which point to specific 
    // bit in the hash registers
    
    HashValue = (UCHAR)((CRC >> (32 - HASH_BITS)) & 0x3f);
    
    DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -CalculateHashValue [0x%.8X]\r\n"), HashValue));
    
    return HashValue;

}


//------------------------------------------------------------------------------
//
// Function: AddMultiCast
//
// This function adds the Hash value to the Hash table(GAUR and GALR).
//
// Parameters:
//      pAddr
//          [in] pointer to a ethernet address.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void AddMultiCast( UCHAR *pAddr )
{
	UCHAR HashValue = 0;
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +AddMultiCast\r\n")));
	
	HashValue = CalculateHashValue( pAddr );
	
	if( HashValue > 31 )
		SETREG32(&gpFECReg->GAUR, 1 << (HashValue-32));
	else
		SETREG32(&gpFECReg->GALR, 1 << HashValue);
	
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -AddMultiCast\r\n")));
}

//------------------------------------------------------------------------------
//
// Function: ClearAllMultiCast
//
// This function clears the Hash table(GAUR and GALR).
//
// Parameters:
//      None.
//
// Returns:
//      None.
//
//------------------------------------------------------------------------------
void ClearAllMultiCast()
{
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: +ClearAllMultiCast\r\n")));
	
	// clear all GAUR and GALR bits
	
	CLRREG32(&gpFECReg->GAUR, 0xFFFFFFFF);
	CLRREG32(&gpFECReg->GALR, 0xFFFFFFFF);
	
	DEBUGMSG(ZONE_FUNCTION, (TEXT("FEC: -ClearAllMultiCast\r\n")));
}

⌨️ 快捷键说明

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