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

📄 smsc911x.c

📁 smsc911x.c smsc911x driver based vxworks network com 9700 stb cware dirver
💻 C
📖 第 1 页 / 共 5 页
字号:

	/* Calculate the total memory for all the M-Blks and CL-Blks. */

	smsc911xMclBlkConfig.mBlkNum = pDrvCtrl->numFrames*2;
	smsc911xClDescTbl[0].clNum = pDrvCtrl->numFrames;
	smsc911xMclBlkConfig.clBlkNum = smsc911xClDescTbl[0].clNum;

	smsc911xMclBlkConfig.memSize = (smsc911xMclBlkConfig.mBlkNum *
			(MSIZE + sizeof (long))) +
			(smsc911xMclBlkConfig.clBlkNum *
			(CL_BLK_SZ + sizeof(long)));

	if ((smsc911xMclBlkConfig.memArea = (char *) memalign (sizeof(long),
			smsc911xMclBlkConfig.memSize)) == NULL) 
	{
		SMSC_TRACE(" system memory unavailable\r\n-smsc911xMemInit\r\n") ;	
		return (ERROR);
	}

	/* Calculate the memory size of all the clusters. */
	smsc911xClDescTbl[0].memSize = (smsc911xClDescTbl[0].clNum *
				(SMSC911X_BUFSIZE + 8)) + sizeof(int);

	/* Allocate the memory for the clusters from cache safe memory. */
	smsc911xClDescTbl[0].memArea =
			(char *) cacheDmaMalloc (smsc911xClDescTbl[0].memSize);

	if ((int)smsc911xClDescTbl[0].memArea == NULL)
	{
		SMSC_TRACE("system memory unavailable\r\n-smsc911xMemInit\r\n");
		return (ERROR);
	}

	/* Initialize the memory pool. */
	if (netPoolInit(pDrvCtrl->endObj.pNetPool, &smsc911xMclBlkConfig,
				&smsc911xClDescTbl[0], smsc911xClDescTblNumEnt,
				NULL) == ERROR)
	{
		SMSC_TRACE(" Could not init buffering\r\n-smsc911xMemInit\r\n");
		return (ERROR);
	}

	/* Store a reference to the cluster pool */
	
	if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool,
			sizeof (TX_PKT), FALSE))
			== NULL)
	{
		SMSC_TRACE("Could not get pool id\r\n-smsc911xMemInit\r\n");
		return (ERROR);
	}

	/*
	* If you need clusters to store received packets into then get them
	* here ahead of time.
	*/
	pDrvCtrl->pTxBase = (TX_PKT *)calloc(TX_PACKETS * sizeof(TX_PKT),1);
	pDrvCtrl->pTxReadIndex = pDrvCtrl->pTxBase;
	pDrvCtrl->pTxWriteIndex = pDrvCtrl->pTxBase;

	pDrvCtrl->pRxBase = (RX_PKT *)calloc(RX_PACKETS * sizeof(RX_PKT),1);
	pDrvCtrl->pRxReadIndex = pDrvCtrl->pRxBase;
	pDrvCtrl->pRxWriteIndex = pDrvCtrl->pRxBase;

	pDrvCtrl->sendBuf = (unsigned char *)calloc(2048, 1);

	SMSC_TRACE(" smsc911xMemInit success\r\n");
	SMSC_TRACE("-smsc911xMemInit\r\n");

	return OK;
}


void Mac_Initialize(PPRIVATE_DATA privateData)
{
	SMSC_ASSERT(privateData!=NULL);

	/*nothing to do here in the simple driver
	    but this function is kept as a place holder. */
}

void smscDelay(unsigned uCount)
{
	int i;
	while ( uCount-->0) 
		for(i=0; i<50; i++);
}

BOOLEAN Lan_Initialize( PPRIVATE_DATA privateData, DWORD dwIntCfg)
{
	BOOLEAN result=FALSE;
	DWORD dwTimeOut=0;
	DWORD dwTemp=0;
	DWORD dwBase = privateData->dwLanBase ;

       SMSC_TRACE("+Lan_Initialize(dwIntCfg=0x%08lX)\r\n",dwIntCfg);
	SMSC_ASSERT(privateData!=NULL);

	/* check to see the device is ready */
	dwTimeOut = 10000 ;
	dwTemp = Lan_GetRegDW(dwBase, PMT_CTRL) ;
	while ( !(dwTemp & PMT_CTRL_READY_) && dwTimeOut>0 )
	{
		smscDelay(10) ;
		dwTemp= Lan_GetRegDW(dwBase, PMT_CTRL) ;
		dwTimeOut -- ;
	}
	if (!(dwTemp & PMT_CTRL_READY_)) {
		SMSC_WARNING(" Device Not Ready \r\n") ;
		goto DONE ;
	}

	/* Reset the LAN911x */
	Lan_SetRegDW(dwBase, HW_CFG,HW_CFG_SRST_);
	dwTimeOut=100000;
	do {
		smscDelay(10);
		dwTemp=Lan_GetRegDW(dwBase, HW_CFG);
		dwTimeOut--;
	} while((dwTimeOut>0)&&(dwTemp&HW_CFG_SRST_));
	if(dwTemp&HW_CFG_SRST_) {
		SMSC_WARNING("  Failed to complete reset.\r\n");
		goto DONE;
	}

	Lan_SetRegDW(dwBase, HW_CFG,0x00050000UL);
	Lan_SetRegDW(dwBase, AFC_CFG,0x006E3740UL);

	/* make sure EEPROM has finished loading before setting GPIO_CFG */
	dwTimeOut=50;
	while((dwTimeOut>0)&&(Lan_GetRegDW(dwBase, E2P_CMD)&E2P_CMD_EPC_BUSY_)) {
		smscDelay(10);
		dwTimeOut--;
	}
	if(dwTimeOut==0) {
		SMSC_WARNING("Lan_Initialize: Timed out waiting for EEPROM busy bit to clear\r\n");
	}

	/* set gpio */
	Lan_SetRegDW(dwBase, GPIO_CFG,0x70000000UL);

	/* initialize interrupts */
	Lan_SetRegDW(dwBase,INT_EN,0);
	Lan_SetRegDW(dwBase,INT_STS,0xFFFFFFFFUL);
	dwIntCfg|=INT_CFG_IRQ_EN_;
	Lan_SetRegDW(dwBase,INT_CFG,dwIntCfg);

	result=TRUE;

DONE:
	SMSC_TRACE("-Lan_Initialize\r\n");
	return result;
}

void Tx_WriteFifo(
	DWORD dwLanBase,
	DWORD *pdwBuf,
	DWORD dwDwordCount)
{
	volatile DWORD *pdwReg;
	pdwReg = (volatile DWORD *)(dwLanBase+TX_DATA_FIFO);
	while(dwDwordCount)
	{
		*pdwReg = *pdwBuf++;
		dwDwordCount--;
	}
}

void Rx_ReadFifo(
	DWORD dwLanBase,
	DWORD *pdwBuf,
	DWORD dwDwordCount)
{
	const volatile DWORD * const pdwReg = 
		(const volatile DWORD * const)(dwLanBase+RX_DATA_FIFO);
	
	while (dwDwordCount)
	{
		*pdwBuf++ = *pdwReg;
		dwDwordCount--;
	}
}

#ifdef USE_PHY_WORK_AROUND
BOOLEAN Phy_Reset(PPRIVATE_DATA privateData)
{
	BOOLEAN result=FALSE;
	WORD wTemp=0;
	DWORD dwLoopCount=100000;
	SMSC_TRACE("+Performing PHY BCR Reset\r\n");
	Phy_SetRegW(privateData,PHY_BCR,PHY_BCR_RESET_);
	do {
		smscDelay(10);
		wTemp=Phy_GetRegW(privateData,PHY_BCR);
		dwLoopCount--;
	} while((dwLoopCount>0)&&(wTemp&PHY_BCR_RESET_));
	if(wTemp&PHY_BCR_RESET_) {
		SMSC_WARNING("Phy Reset failed to complete.\r\n");
		goto DONE;
	}
	/*extra delay required because the phy may not be completed with its reset
	//  when PHY_BCR_RESET_ is cleared.
	//  They say 256 uS is enough delay but I'm using 500 here to be safe */
	smscDelay(500);
	result=TRUE;
DONE:
	return result;
}

DWORD Phy_LBT_GetTxStatus(PPRIVATE_DATA privateData)
{
	DWORD dwBase = privateData->dwLanBase ;
	DWORD result=Lan_GetRegDW(dwBase, TX_FIFO_INF);
	result&=TX_FIFO_INF_TSUSED_;
	if(result!=0x00000000UL) {
		result=Lan_GetRegDW(dwBase,TX_STATUS_FIFO);
	} else {
		result=0;
	}
	return result;
}

DWORD Phy_LBT_GetRxStatus(PPRIVATE_DATA privateData)
{
	DWORD dwBase = privateData->dwLanBase ;
	DWORD result=Lan_GetRegDW(dwBase,RX_FIFO_INF);
	if(result&0x00FF0000UL) {
		/* Rx status is available, read it */
		result=Lan_GetRegDW(dwBase,RX_STATUS_FIFO);
	} else {
		result=0;
	}
	return result;
}

BOOLEAN Phy_CheckLoopBackPacket(PPRIVATE_DATA privateData)

{
	BOOLEAN result=FALSE;
	DWORD tryCount=0;
	DWORD dwLoopCount=0;
	DWORD dwBase = privateData->dwLanBase ;
	
	for(tryCount=0;tryCount<10;tryCount++)
	{
		DWORD dwTxCmdA=0;
		DWORD dwTxCmdB=0;
		DWORD dwStatus=0;
		DWORD dwPacketLength=0;

		/* zero-out Rx Packet memory */
		bzero(privateData->LoopBackRxPacket,MIN_PACKET_SIZE);

		/* write Tx Packet to 118 */
		dwTxCmdA=
			((((DWORD)(privateData->LoopBackTxPacket))&0x03UL)<<16) | 
			TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_ |
			((DWORD)(MIN_PACKET_SIZE));
		dwTxCmdB=
			(((DWORD)(MIN_PACKET_SIZE))<<16) |
			((DWORD)(MIN_PACKET_SIZE));
		Lan_SetRegDW(dwBase,TX_DATA_FIFO,dwTxCmdA);
		Lan_SetRegDW(dwBase,TX_DATA_FIFO,dwTxCmdB);
		Tx_WriteFifo(
			privateData->dwLanBase,
			(DWORD *)(((DWORD)(privateData->LoopBackTxPacket))&0xFFFFFFFCUL),
			(((DWORD)(MIN_PACKET_SIZE))+3+
			(((DWORD)(privateData->LoopBackTxPacket))&0x03UL))>>2);

		/* wait till transmit is done */
		dwLoopCount=60;
		while((dwLoopCount>0)&&((dwStatus=Phy_LBT_GetTxStatus(privateData))==0)) {
			smscDelay(5);
			dwLoopCount--;
		}
		if(dwStatus==0) {
			SMSC_WARNING("Failed to Transmit during Loop Back Test\r\n");
			continue;
		}
		if(dwStatus&0x00008000UL) {
			SMSC_WARNING("Transmit encountered errors during Loop Back Test\r\n");
			continue;
		}

		/* wait till receive is done */
		dwLoopCount=60;
		while((dwLoopCount>0)&&((dwStatus=Phy_LBT_GetRxStatus(privateData))==0))
		{
	         smscDelay(5);
	         dwLoopCount--;
		}
		if(dwStatus==0) {
			SMSC_WARNING("Failed to Receive during Loop Back Test\r\n");
			continue;
		}
		if(dwStatus&RX_STS_ES_)
		{
			SMSC_WARNING("Receive encountered errors during Loop Back Test\r\n");
			continue;
		}

		dwPacketLength=((dwStatus&0x3FFF0000UL)>>16);

		Rx_ReadFifo(
			privateData->dwLanBase,
			((DWORD *)(privateData->LoopBackRxPacket)),
			(dwPacketLength+3+(((DWORD)(privateData->LoopBackRxPacket))&0x03UL))>>2);

		if(dwPacketLength!=(MIN_PACKET_SIZE+4)) {
			SMSC_WARNING("Unexpected packet size during loop back test, size=%ld, will retry\r\n",dwPacketLength);
		} else {
			DWORD byteIndex=0;
			BOOLEAN foundMissMatch=FALSE;
			for(byteIndex=0;byteIndex<MIN_PACKET_SIZE;byteIndex++) {
				if(privateData->LoopBackTxPacket[byteIndex]!=privateData->LoopBackRxPacket[byteIndex])
				{
					foundMissMatch=TRUE;
					break;
				}
			}
			if(!foundMissMatch) {
				SMSC_TRACE("Successfully Verified Loop Back Packet\r\n");
				result=TRUE;
				goto DONE;
			} else {
				SMSC_WARNING("Data miss match during loop back test, will retry.\r\n");
			}
		}
	}
DONE:
	return result;
}
BOOLEAN Phy_LoopBackTest(PPRIVATE_DATA privateData)
{
	BOOLEAN result=FALSE;
	DWORD byteIndex=0;
	DWORD tryCount=0;
	DWORD dwBase = privateData->dwLanBase ;
	/* Initialize Tx Packet */
	for(byteIndex=0;byteIndex<6;byteIndex++) {
		/* use broadcast destination address */
		privateData->LoopBackTxPacket[byteIndex]=(BYTE)0xFF;
	}
	for(byteIndex=6;byteIndex<12;byteIndex++) {
		/* use incrementing source address */
		privateData->LoopBackTxPacket[byteIndex]=(BYTE)byteIndex;
	}
	/* Set length type field */
	privateData->LoopBackTxPacket[12]=0x00;
	privateData->LoopBackTxPacket[13]=0x00;
	for(byteIndex=14;byteIndex<MIN_PACKET_SIZE;byteIndex++)
	{
		privateData->LoopBackTxPacket[byteIndex]=(BYTE)byteIndex;
	}
	{
		DWORD dwRegVal=Lan_GetRegDW(dwBase, HW_CFG);
		dwRegVal&=HW_CFG_TX_FIF_SZ_;
		dwRegVal|=HW_CFG_SF_;
		Lan_SetRegDW(dwBase,HW_CFG,dwRegVal);
	}
	Lan_SetRegDW(dwBase,TX_CFG,TX_CFG_TX_ON_);
	Lan_SetRegDW(dwBase,RX_CFG,(((DWORD)(privateData->LoopBackRxPacket))&0x03)<<8);

	/* Set Phy to 10/FD, no ANEG, */
	Phy_SetRegW(privateData,PHY_BCR,0x0100);

	/* enable MAC Tx/Rx, FD */
	Mac_SetRegDW(dwBase ,MAC_CR,MAC_CR_FDPX_|MAC_CR_TXEN_|MAC_CR_RXEN_);

	/* set Phy to loopback mode */
	Phy_SetRegW(privateData,PHY_BCR,0x4100);

	for(tryCount=0;tryCount<10;tryCount++) {
		if(Phy_CheckLoopBackPacket(privateData))
		{
			result=TRUE;
			goto DONE;
		}
		privateData->dwResetCount++;
		/* disable MAC rx */
		Mac_SetRegDW(privateData,MAC_CR,0UL);
		Phy_Reset(privateData);

		/* Set Phy to 10/FD, no ANEG, and Loopbackmode */
		Phy_SetRegW(privateData,PHY_BCR,0x4100);

		/* enable MAC Tx/Rx, FD */
		Mac_SetRegDW(dwBase,MAC_CR,MAC_CR_FDPX_|MAC_CR_TXEN_|MAC_CR_RXEN_);
	}
DONE:
	/* disable MAC */
	Mac_SetRegDW(dwBase,MAC_CR,0UL);
	/* Cancel Phy loopback mode */
	Phy_SetRegW(privateData,PHY_BCR,0U);

	Lan_SetRegDW(dwBase, TX_CFG,0UL);
	Lan_SetRegDW(dwBase, RX_CFG,0UL);

	return result;
}

#endif /* USE_PHY_WORK_AROUND */


void Phy_SetLink(PPRIVATE_DATA privateData) 
{
	WORD wTemp;

	/*Because this is part of the single threaded initialization
	//  path there is no need to acquire the MacPhyAccessLock */

	wTemp=Phy_GetRegW(privateData, PHY_ANEG_ADV);
	/* Advertise all speeds and pause capabilities*/
	wTemp|=(PHY_ANEG_ADV_PAUSE_|PHY_ANEG_ADV_SPEED_);
	Phy_SetRegW(privateData,PHY_ANEG_ADV,wTemp);

	/* begin to establish link */
	Phy_SetRegW(privateData,
		PHY_BCR,
		PHY_BCR_AUTO_NEG_ENABLE_|
		PHY_BCR_RESTART_AUTO_NEG_);
}

BOOLEAN Phy_Initialize( PPRIVATE_DATA privateData, DWORD dwPhyAddr)
{
	BOOLEAN result=FALSE;
#ifndef USE_PHY_WORK_AROUND
	WORD wTemp=0;
#endif
	WORD wPhyId1=0;
	WORD wPhyId2=0;
#ifndef USE_PHY_WORK_AROUND
	DWORD dwLoopCount=0;
#endif
	DWORD dwBase = privateData->dwLanBase ;

	SMSC_TRACE("-Phy_Initialize\r\n");
	SMSC_ASSERT(privateData!=NULL);

⌨️ 快捷键说明

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