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

📄 at91emacend.c

📁 atmel9200 vxworks bsp
💻 C
📖 第 1 页 / 共 4 页
字号:
*
* This routine adds a multicast address to whatever the driver
* is already listening for.  It then resets the address filter.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS at91EndMCastAdd
    (
    at91end_device *pDrvCtrl,	/* device pointer */
    char* pAddress		/* new address to add */
    )
{
    int error;

    if ( (error = etherMultiAdd (&pDrvCtrl->end.multiList,
		pAddress)) == ENETRESET )
	    at91EndConfig (pDrvCtrl);

    return (OK);
}

/*****************************************************************************
*
* at91EndMCastDel - delete a multicast address for the device
*
* This routine removes a multicast address from whatever the driver
* is listening for.  It then resets the address filter.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS at91EndMCastDel
    (
    at91end_device* pDrvCtrl,	/* device pointer */
    char* pAddress		/* address to be deleted */
    )
{
    int error;

    if ((error = etherMultiDel (&pDrvCtrl->end.multiList,
	     (char *)pAddress)) == ENETRESET)
	    at91EndConfig (pDrvCtrl);
    return (OK);
}

/*****************************************************************************
*
* at91EndMCastGet - get the multicast address list for the device
*
* This routine gets the multicast list of whatever the driver
* is already listening for.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS at91EndMCastGet
    (
    at91end_device* pDrvCtrl,	/* device pointer */
    MULTI_TABLE* pTable		/* address table to be filled in */
    )
{
    int error;

    error = etherMultiGet (&pDrvCtrl->end.multiList, pTable);

    return (error);
}

/*******************************************************************************
*
* at91EndStop - stop the device
*
* This function calls BSP functions to disconnect interrupts and stop
* the device from operating in interrupt mode.
*
* RETURNS: OK or ERROR.
*/

LOCAL STATUS at91EndStop
    (
    at91end_device *pDrvCtrl	/* device to be stopped */
    )
{
	EMAC_S* pemac = (EMAC_S*)EMAC_BASE_ADDR;
	ENDLOGMSG ((" Enter   at91EndStop routine...\n", 1, 2, 3, 4, 5, 6));
	
	/*
	 *	disable rx and tx, and int
	 */

	pemac ->EMAC_CTL = EMAC_CTL_CSR;
	pemac ->EMAC_IDR = 0xFFFFFFFF;

	intDisable ( pDrvCtrl->level );
	END_FLAGS_CLR (&pDrvCtrl->end, IFF_UP | IFF_RUNNING);
	ENDLOGMSG ((" Leave   at91EndStop routine...\n", 1, 2, 3, 4, 5, 6));
	
    return (OK);
}

/******************************************************************************
*
* at91EndUnload - unload a driver from the system
*
* This function first brings down the device, and then frees any
* stuff that was allocated by the driver in the load function.
*
* RETURNS: OK or ERROR.
*/

LOCAL void FreeEndMemory(  at91end_device* pDrvCtrl )
{
	if ( pDrvCtrl->end.pNetPool )
	{
		netPoolDelete (pDrvCtrl->end.pNetPool);
		free (pDrvCtrl->end.pNetPool);
		pDrvCtrl->end.pNetPool = (NET_POOL_ID)0;
	}
	
	if (at91endClDescTbl[0].memArea)
	{
		cacheDmaFree (at91endClDescTbl[0].memArea);
		at91endClDescTbl[0].memArea = (char *)0;
	}
	
	if( pDrvCtrl ->TranFifoBuf )
	{
		cacheDmaFree( pDrvCtrl ->TranFifoBuf );
		pDrvCtrl ->RecvBufDesc = NULL;
		pDrvCtrl ->TranFifoBuf = NULL;
		pDrvCtrl ->RecvFifoBuf = NULL;
		bzero( (void*)&(pDrvCtrl->pTxBufStart[0]), sizeof( AT91_END_TRAN_FD	)*TX_FD_NUM );
	}
	
	if (at91endMclConfig.memArea)
	{
		free (at91endMclConfig.memArea);
		at91endMclConfig.memArea = (char *)0;
	}
	
	if (pDrvCtrl)
	{
		free (pDrvCtrl);
		(at91end_device*)pDrvCtrl = 0;
	}

}

LOCAL STATUS at91EndUnload
    (
    at91end_device* pDrvCtrl	/* device to be unloaded */
    )
{
    END_OBJECT_UNLOAD (&pDrvCtrl->end);   /*this call will indicate */
										  /* protocol that the device will be unloaded */

    /* TODO - Free any shared DMA memory */

	at91EndStop(pDrvCtrl);   	/*before unloading the device will stop functioning*/
	at91EmacReset(pDrvCtrl);		/*then it will reset the registers in order to clear any pending interrupts */
	at91EndFdFree(pDrvCtrl);
	FreeEndMemory( pDrvCtrl );

    return (OK);
}

/******************************************************************************
* at91EmacReset - Reset the device
* This function resets the driver after initializing from at91EndLoad
*/

LOCAL void	at91EmacReset
    (
    at91end_device* pDrvCtrl	/* device to be reset */
    )
{
	UINT32 dummy, i;
	UINT32 tmp = 0xFFFFFFFF;
	EMAC_S *pemac = (EMAC_S*)EMAC_BASE_ADDR;
	if(pDrvCtrl->unit != 0)
		return;
	/*
	 *	disable interrupt first
	 */
	pemac ->EMAC_IDR = 0xFFFFFFFF;
	/*
	 *	disable recive and transmit 
	 */
	pemac ->EMAC_CTL = EMAC_CTL_CSR;
	/*
	 *	config EMAC state, MAX HCLK = (60-100)/16 < 8M (for LXT971)
	 */
	pemac ->EMAC_CFG = EMAC_CFG_CLK_HCLK_16 | EMAC_CFG_RMII /*bao  | EMAC_CFG_SPD/*| EMAC_CFG_MTI | EMAC_CFG_UNI*/;
	/*
	 *	clear transmit and receive status bit
	 */
	pemac ->EMAC_TSR = tmp;
	pemac ->EMAC_RSR = tmp;
	/*
	 *	clear interrupt status REG
	 */
	dummy = pemac ->EMAC_ISR;
	/*
	 *	set all statistic regoster by read it
	 */

	for( i = 0; i< sizeof(ETH_STAT_S)/sizeof(AT91_REG); i++ )
	{
		dummy = ( (AT91_REG*)( &(pemac ->ESTAT ) ) )[i];
	}
	
	/*
	 *	after reset, we need to set address for mac
	 */

	/*
	 *	
	 */


	return;
}

/******************************************************************************
* at91EndPhyRead - Read PHY device
* This function is used to read a byte from the PHY device
*/
LOCAL UINT32 at91EndPhyRead
	(
	UINT32 phyRegAddr, 	/* Address of PHY register to be read */
	UINT32 phyAddr		/* Address of the PHY chip (usually 0 for single PHY) */
	)
{
	EMAC_S* regs = (EMAC_S*)EMAC_BASE_ADDR;
	UINT32 dummy;

	regs->EMAC_MAN = EMAC_PHY_HIGH | EMAC_PHY_CODE | EMAC_PHY_RW_R
		| (phyRegAddr << 18);
	
	/* Wait until IDLE bit in Network Status register is cleared */
	/* TODO: Enforce some maximum loop-count?*/
	dummy = 0;
	while ( !(regs->EMAC_SR & EMAC_SR_IDLE)&& (dummy++ < 10000) ) ;
		
	return ( regs->EMAC_MAN & 0x0000ffff );
}

/******************************************************************************
* at91EndPhyWrite	- Wrire into PHY device
* This function is used to write a byte to the PHY device
*/
LOCAL void at91EndPhyWrite
	(
	UINT32 phyRegAddr, 	/* Address of PHY register to be written */
	UINT32 phyAddr,		/* Address of the PHY chip (usually 0 for single PHY) */
	UINT32 phyData		/* Data to be written */
	)
{
	EMAC_S* regs = (EMAC_S*)EMAC_BASE_ADDR;
	UINT32 dummy;

	regs->EMAC_MAN = (EMAC_PHY_HIGH | EMAC_PHY_CODE | EMAC_PHY_RW_R
		| (phyRegAddr << 18)) + (phyData & 0xffff);
	
	/* Wait until IDLE bit in Network Status register is cleared */
	/* TODO: Enforce some maximum loop-count?*/
	dummy = 0;
	while (!(regs->EMAC_SR & EMAC_SR_IDLE)&(dummy++ < 10000) ) ;
}


/******************************************************************************
* at91EndMacIntialize - Initialize MAC/BDMA registers
* Initialize the MAC and BDMA registers to make the Ethernet interface functional
*/
LOCAL void at91EndMacInitialize
	(
	at91end_device *pDevice	/* Device that has to be initialized */
	)
{

	EMAC_S* pemac = (EMAC_S*)EMAC_BASE_ADDR;
	
	/*
	 *	set the first address as the IF mac address
	 */
	FormatETHSpecialAddrWord( &(pDevice ->addrListHigh[0]), 
		&(pDevice ->addrListLow[0]), (BYTE*)pDevice->enetAddr );

	/*
	 *	write the special address to chip
	 */
	pemac ->EMAC_SA1L = pDevice ->addrListLow[0];
	pemac ->EMAC_SA1H = pDevice ->addrListHigh[0];

	if( pDevice ->mcastAddrCount > 0 )
	{
		pemac ->EMAC_SA2L = pDevice ->addrListLow[1];
		pemac ->EMAC_SA2H = pDevice ->addrListHigh[1];
	}
	else
	{
		pemac ->EMAC_SA2L = 0;
		pemac ->EMAC_SA2H = 0;
	}

	if( pDevice ->mcastAddrCount > 1 )
	{
		pemac ->EMAC_SA3L = pDevice ->addrListLow[2];
		pemac ->EMAC_SA3H = pDevice ->addrListHigh[2];
	}
	else
	{
		pemac ->EMAC_SA3L = 0;
		pemac ->EMAC_SA3H = 0;
	}
	
	if( pDevice ->mcastAddrCount > 2 )
	{
		pemac ->EMAC_SA4L = pDevice ->addrListLow[3];
		pemac ->EMAC_SA4H = pDevice ->addrListHigh[3];
	}
	else
	{
		pemac ->EMAC_SA4L = 0;
		pemac ->EMAC_SA4H = 0;
	}

	/*
	 *	what use for hash reg?, write all one first
	 */

	pemac ->EMAC_HSH = 0xFFFFFFFF;
	pemac ->EMAC_HSL = 0xFFFFFFFF;

	/*
	 *	setup receive buffer address
	 */
	pemac ->EMAC_RBQP = (AT91_REG)(pDevice ->RecvBufDesc);
	
	/*
	 *	write configuration register again, do not allow mulitcast and unicast 
	 */
	pemac ->EMAC_CFG  = EMAC_CFG_CLK_HCLK_16  | EMAC_CFG_RMII /*bao  | EMAC_CFG_SPD/*| EMAC_CFG_MTI | EMAC_CFG_UNI*/;

	
	return;
	
}


/**********************************************************************************
*    at91EndFdInitialize - Initialize TX and RX FD lists
*    Make a circular list of Rx and TX frame descriptors and buffers.
*    Two global variables gpReceiveFrameDescStart and gpTransmitFrameDescStart 
*    stores the pointer to the start of the list.  BDMA TX/RX PTR registers are 
*    also initialized with the start of the appropriate list.
*/

LOCAL STATUS at91EndFdInitialize
    (
    at91end_device* pDrvCtrl	/* device to be initialized */
    )
{

    int count;

	char *pNewCluster;

	if( pDrvCtrl ->RecvFifoBuf == NULL )
	{
		ENDLOGMSG( ( "END: at91EndFdInitialize find RX fifo have no buffer, something gong wrong ! ", 1,2,3,4,5,6 ));
		at91EndFdFree( pDrvCtrl );
		return (ERROR);

	}

	for( count = 0; count < RX_FD_NUM; count++ )
	{
	    
		pNewCluster = pDrvCtrl ->RecvFifoBuf + count*(pDrvCtrl ->TranPkgSize);
		/*	netClusterGet ( pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId );*/
		
	
/*
		if ( pNewCluster == NULL )
	    {
			ENDLOGMSG(( "END:Get clust failure in routine at91EndFdInitialize\n", 1,2,3,4,5, 6 ));
			at91EndFdFree( pDrvCtrl );
			return ERROR;
	    }
*/

		pDrvCtrl ->clPointBuf[ count ] = pNewCluster;

		if( ((UINT32)pNewCluster)&0x3 != 0 )
		{
			ENDLOGMSG(( "END:receive buffer address not at wordalign in routine at91EndFdInitialize. point: %x\n", (UINT32)pNewCluster ,2,3,4,5, 6 ))
		}

		/*
		 *	just make the point align to word
		 */
		
		(pDrvCtrl ->RecvBufDesc)[count].bufaddr = ( ( ((UINT32)pNewCluster)+3 )&(0xFFFFFFFC) );
		(pDrvCtrl ->RecvBufDesc)[count].recvstatus = 0;

	}/* end of for loop*/

	(pDrvCtrl ->RecvBufDesc)[RX_FD_NUM - 1].bufaddr |= EMAC_RECV_DESC_WRAP;
	pDrvCtrl ->rxBufPtr = 0;

	/*
	 *	initialize tx desc query
	 */
	if( (pDrvCtrl ->TranFifoBuf) == NULL )
	{
		ENDLOGMSG( ( "END: at91EndFdInitialize find TX fifo have no buffer, something gong wrong ! ", 1,2,3,4,5,6 ));
		at91EndFdFree( pDrvCtrl );
		return (ERROR);
	}

	for( count = 0; count < TX_FD_NUM; count ++ )
	{
		(pDrvCtrl ->pTxBufStart)[ count ].bufaddr = 
			pDrvCtrl ->TranFifoBuf + count*(pDrvCtrl ->TranPkgSize);
		(pDrvCtrl ->pTxBufStart)[ count ].owner = 0;	/*init owner to software */
	}
	pDrvCtrl ->TxTailPtr = pDrvCtrl ->TxPtr = 0;
	pDrvCtrl ->TXFifoStat = TXFIFOEMPTY;

	pDrvCtrl->fdInitialized = TRUE;
	return OK;
}

/******************************************************************************
*	at91EndFdFree - Free the allocated TX and RX FD lists and buffers
*	This function frees all the allocated TX and RX FDs and the associated
*	buffers
*/

LOCAL void at91EndFdFree
    (
    at91end_device* pDrvCtrl	/* device to be freed */
    )
{
	UINT32 count;
	char* tmpcl;

/*
	if (pDrvCtrl->fdInitialized == FALSE)
		return;
*/
/*
	if( pDrvCtrl ->RecvBufDesc )
	{
		for ( count = 0; count < RX_FD_NUM; count++ )
		{
			tmpcl = pDrvCtrl ->clPointBuf[ count ];
			if( tmpcl )
			{
				netClFree (pDrvCtrl->end.pNetPool, tmpcl );
			}
			(pDrvCtrl ->RecvBufDesc)[count].bufaddr = 0;
			pDrvCtrl ->clPointBuf[ count ] = NULL;
		}
	}
*/
	pDrvCtrl->fdInitialized = FALSE;
}


#endif 	/* INCLUDE_SNDS_END */

⌨️ 快捷键说明

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