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

📄 mac8947.c

📁 source code of armboot for s3c4510
💻 C
📖 第 1 页 / 共 2 页
字号:
	ushort*					pFrameData;	ulong 					frameLength;    ulong					BdmaAddr=api_Mac_dev->BdmaAddr;	REG_IN_LONG(BdmaAddr, BDMASTAT ,bdmaStat.stat_resetval);	REG_OUT_LONG(BdmaAddr, BDMASTAT ,bdmaStat.stat_resetval);	REG_IN_LONG(BdmaAddr, BDMARXPTR, *(ulong *)(&pReceiveFrameDesc));	if ((*(ulong *) (&(api_Mac_dev->gpReceiveFrameDescStart)->rxStatusLength)) == 0)		return;    do 	{		/*		 * Check if Null list interrupt has occurred.  If yes, reset		 * and restart the Ethernet MAC (as given in Samsung sample code.		 */		if (bdmaStat.stat_reg.bdmaRxNullList)		{			api_MacHWStop(api_Mac_dev);	/* Stop RX and TX */			api_MacHWReset(api_Mac_dev);	/* reset the chip */			api_MacBuffFree(api_Mac_dev);	/* Free the FDs */			api_MacBuffInit(api_Mac_dev);	/* Reinitialize FDs */			api_MacHWInit(api_Mac_dev);	/* Initialize MAC */			api_MacHWStart(api_Mac_dev);	/* Start RX and TX */			break;		}		/*		 * Received a good frame		 */		frameLength = (api_Mac_dev->gpReceiveFrameDescStart)->rxStatusLength.frameLength;		if ((api_Mac_dev->gpReceiveFrameDescStart)->rxStatusLength.good)		{			api_Mac_dev->statistics.rxGood++;			pFrameData = (ushort *)((api_Mac_dev->gpReceiveFrameDescStart)->rxFrameData.frameDataPtr);			    /* Pass the packet up to the protocol layers. */		    NetRxPackets[api_Mac_dev->statistics.rxGood%RX_FD_NUM] = (uchar *)(pFrameData);    		NetReceive(NetRxPackets[api_Mac_dev->statistics.rxGood%RX_FD_NUM], frameLength);			/*SYS_MAC_RECV(api_Mac_dev, (char *)pFrameData, frameLength);			*/		}		else	/* Update error statistics counters */		{			api_Mac_dev->statistics.rxBad++;			if ((api_Mac_dev->gpReceiveFrameDescStart)->rxStatusLength.ovMax)				api_Mac_dev->statistics.rxOvMaxSize++;			if ((api_Mac_dev->gpReceiveFrameDescStart)->rxStatusLength.ctlRcv)				api_Mac_dev->statistics.rxCtlRecd++;			if ((api_Mac_dev->gpReceiveFrameDescStart)->rxStatusLength.rx10Stat)				api_Mac_dev->statistics.rx10Stat++;			if ((api_Mac_dev->gpReceiveFrameDescStart)->rxStatusLength.alignErr)				api_Mac_dev->statistics.rxAlignErr++;			if ((api_Mac_dev->gpReceiveFrameDescStart)->rxStatusLength.crcErr)				api_Mac_dev->statistics.rxCRCErr++;			if ((api_Mac_dev->gpReceiveFrameDescStart)->rxStatusLength.overFlow)				api_Mac_dev->statistics.rxOverflowErr++;			if ((api_Mac_dev->gpReceiveFrameDescStart)->rxStatusLength.longErr)				api_Mac_dev->statistics.rxLongErr++;			if ((api_Mac_dev->gpReceiveFrameDescStart)->rxStatusLength.rxPar)				api_Mac_dev->statistics.rxParErr++;			if ((api_Mac_dev->gpReceiveFrameDescStart)->rxStatusLength.rxHalted)				api_Mac_dev->statistics.rxHalted++;		}				*(ulong *)(&(api_Mac_dev->gpReceiveFrameDescStart)->rxStatusLength) = 0;	/* Rx status length field */		(api_Mac_dev->gpReceiveFrameDescStart)->rxFrameData.o_bit = 1;	/* Ownership back to BDMA */				(api_Mac_dev->gpReceiveFrameDescStart) = (api_Mac_dev->gpReceiveFrameDescStart)->nextRxFrameDesc;	} while ((api_Mac_dev->gpReceiveFrameDescStart) != pReceiveFrameDesc);	/*If not ownerstat than re_enable rx  */	REG_IN_LONG(BdmaAddr, BDMARXCON, *(ulong *) (&bdmaRxCon));		if(bdmaRxCon.rxCon_reg.enable == 0)	{			bdmaRxCon.rxCon_reg.enable = 1;			REG_OUT_LONG(BdmaAddr, BDMARXCON, *(ulong *) (&bdmaRxCon));	}}/********************************************************************************* api_MacSend - .*** RETURNS: OK or ERROR return status why..** SEE ALSO: */int api_MacSend(API_DEVICE *api_Mac_dev, ulong pData, int len){		TRANSMIT_FRAME_DESC 	*pTxFd;	uBDMATXCON 				bdmaTxCon;	uMACTXCON 				macTxCon;    	ulong					pBdmaAddr=api_Mac_dev->BdmaAddr;	ulong					pMacAddr=api_Mac_dev->MacAddr;	*(ulong *)(&bdmaTxCon) = 0;	*(ulong *)(&macTxCon) = 0;#ifdef TEST_MAC_SEND	printf("entering api_MacSend...\n");#endif	if ((api_Mac_dev->gpTransmitFrameDescStart)->txFrameData.o_bit)	/* Ownership with BDMA? */	{		printf("Error: Ownership with BDMA?\n");		return ERROR;	}	pTxFd = (api_Mac_dev->gpTransmitFrameDescStart);			/* <<Attention>> FIXUP Please for RTOS and Application */	/* FIXUP please not Use memory copy */	/*rtn(pData, (void *)pTxFd->txFrameData.frameDataPtr, len); */		pTxFd->txFrameData.frameDataPtr = pData;	pTxFd->txFrameData.frameDataPtr |= NON_CACHE_REGION;		*(ulong *)(&pTxFd->txControl) = 0;	/* Reset control word */	pTxFd->txControl.t_bit = 1;	pTxFd->txControl.a_bit = 1;#if BIG_ENDIAN		pTxFd->txControl.l_bit = 0;#else	/*BIG_ENDIAN*/	pTxFd->txControl.l_bit = 1;#endif	/*BIG_ENDIAN*/	pTxFd->txStatusLength.frameLength = len;	pTxFd->txFrameData.o_bit = 1;    /* place a transmit request */    /* oldLevel = SYS_INT_STOP(MAX_ILEV);*/   /* now sndsEndInt won't get confused */    /* initiate device transmit */	REG_IN_LONG (pBdmaAddr, BDMATXCON, bdmaTxCon.txCon_resetval);	bdmaTxCon.txCon_reg.enable = 1;	REG_OUT_LONG (pBdmaAddr, BDMATXCON, bdmaTxCon.txCon_resetval);		REG_IN_LONG (pMacAddr, MACTXCON, macTxCon.macTxCon_resetval);	macTxCon.macTxCon_reg.transmitEnable = 1;	REG_OUT_LONG (pMacAddr, MACTXCON, macTxCon.macTxCon_resetval);#ifdef TEST_MAC_SEND	printf("initiate device transmit...done\n");#endif    /*SYS_INT_START (oldLevel);*/   /* now sndsEndInt won't get confused */        /* Advance our management index */	(api_Mac_dev->gpTransmitFrameDescStart) = (api_Mac_dev->gpTransmitFrameDescStart)->nextTxFrameDesc;			return OK;}/********************************************************************************* api_MacIntEnable - .*** RETURNS: OK or ERROR return status why..** SEE ALSO: */int api_MacIntEnable(API_DEVICE *api_Mac_dev){	STATUS status = OK;	/* Not use system interrupt handler */	/*	SYS_INT_CONNECT(api_Mac_dev->ivecRx, api_Mac_dev->ihandleFuncRx);	SYS_INT_CONNECT(api_Mac_dev->ivecTx, api_Mac_dev->ihandleFuncTx);	*/	intEnable(api_Mac_dev->ivecRx);	intEnable(api_Mac_dev->ivecTx);	api_Mac_dev->status = INT_ENABLE_STATUS;			return status;}/********************************************************************************* api_MacIntDisable - .*** RETURNS: OK or ERROR return status why..** SEE ALSO: */int api_MacIntDisable(API_DEVICE *api_Mac_dev){	STATUS status = OK;		/* Not use system interrupt handler */	/*	SYS_INT_CONNECT(api_Mac_dev->ivecRx, dummyIsr);	SYS_INT_CONNECT(api_Mac_dev->ivecTx, dummyIsr);	*/		intDisable(api_Mac_dev->ivecRx);	intDisable(api_Mac_dev->ivecTx);		api_Mac_dev->status = INT_DISABLE_STATUS;			return status;}/******************************************************************************* sndsEndPhyRead - Read PHY device* This function is used to read a byte from the PHY device*/ulong miiRead(API_DEVICE *api_Mac_dev, 			  ulong phyAddr,			/* Address of the PHY chip (usually 0 for single PHY) */			  ulong phyRegAddr, 		/* Address of PHY register to be read */			  ulong *phyData)			/* Data to be Read */{	uSTACON 	staCon;	ulong		MacAddr=api_Mac_dev->MacAddr;	*(ulong *) (&staCon) = 0;	staCon.staCon_reg.phyRegisterAddr = phyRegAddr;	staCon.staCon_reg.phyAddr = phyAddr;	staCon.staCon_reg.busy = 1;	REG_OUT_LONG (MacAddr, STACON, staCon.staCon_resetval);	do 	{		REG_IN_LONG(MacAddr, STACON, staCon.staCon_resetval);		} while (staCon.staCon_resetval & 0x800);	/***** Busy bit ***/		REG_IN_LONG(MacAddr, STADATA, *phyData);	return 0;}/******************************************************************************* sndsEndPhyWrite	- Wrire into PHY device* This function is used to write a byte to the PHY device*/void miiWrite(API_DEVICE *api_Mac_dev,			  ulong phyAddr,		/* Address of the PHY chip (usually 0 for single PHY) */			  ulong phyRegAddr, 	/* Address of PHY register to be written */			  ulong phyData)		/* Data to be written */{	uSTACON staCon;	ulong count = 1000;	ulong	MacAddr=api_Mac_dev->MacAddr;	REG_OUT_LONG (MacAddr, STADATA, phyData);	*(ulong *) (&staCon) = 0;	staCon.staCon_reg.phyRegisterAddr = phyRegAddr;	staCon.staCon_reg.phyAddr = phyAddr;	staCon.staCon_reg.busy = 1;	staCon.staCon_reg.write = 1;	REG_OUT_LONG (MacAddr, STACON, staCon.staCon_resetval);	do	{		REG_IN_LONG (MacAddr, STACON, staCon.staCon_resetval);		} while (staCon.staCon_resetval & 0x800)	;	/***** Busy bit ***/	while (count--)		;	/* Dummy delay after PHY write */}/*******************************************************************************   FUNCTION**       MII_AutoNeg**   DESCRIPTION**       Using the mii_ReadMII and mii_WriteMII routines supplied by the driver*       to access the MII registers, this routine directs the auto-negotiation*       process of an MII PHY.**   INPUTS**       *api_Mac_dev       *       phyAddr*       retries        *       *isFullDuplexP *       *is100Mbps     *       miiRead*       miiWrite**   OUTPUTS**       SUCCESS           *                           *                           *       TIMEOUT           *                            *       NOT_PRESENT       *       INVALID_OPERATION *                           *       INVALID_FUNCTION  *       INVALID_POINTER*    *****************************************************************************//*STATUS MII_AutoNeg(DV_DEVICE_ENTRY* deviceP, int phyAddr,                   unsigned long retries, int* isFullDuplexP, int* is100MbpsP,                   mii_ReadMII miiRead, mii_WriteMII miiWrite)*/#if 0STATUS MII_AutoNeg(API_DEVICE *api_Mac_dev, unsigned long retries, int *isFullDuplexP, int *is100MbpsP){	unsigned long 		miiControl;	unsigned long 		miiStatus = 0;	unsigned long 		miiAutoNeg = MII_ADVR_802_3;	unsigned long 		tries = ((unsigned long)(0xFFFFFFFF));	STATUS 				status = OK;	ulong 				phyAddr = 0;	if (api_Mac_dev->channel == 0)	{		phyAddr = PHY_ADDR_A;	}	else	{		phyAddr = PHY_ADDR_B;	}	/* Reset PHY via software */	miiRead(api_Mac_dev, phyAddr, MII_CONTROL, &miiControl);	miiControl |= MII_CTRL_RESET;	miiWrite(api_Mac_dev, phyAddr, MII_CONTROL, miiControl);	/* Wait for PHY to complete reset */	do	{		miiRead(api_Mac_dev, phyAddr, MII_CONTROL, &miiControl);	} while((miiControl & MII_CTRL_RESET) != 0);		/* Power up PHY and set options */	miiControl &= ~(MII_CTRL_LOOPBACK | MII_CTRL_POWER_DOWN |	MII_CTRL_ISOLATE | MII_CTRL_COLL_TEST);	miiControl |= (MII_CTRL_AUTO_NEG);	miiWrite(api_Mac_dev, phyAddr, MII_CONTROL, miiControl);		/* Read PHY status and capabilities */	miiRead(api_Mac_dev, phyAddr, MII_STATUS, &miiStatus);		/* This driver relies on PHY being capable of auto-negotiation */	if((miiStatus & MII_STAT_AUTO_NEG) == 0)	{		status = ERROR;	}	/* Determine PHY capabilities to be advertised during auto-negotiation */	if((miiStatus & MII_STAT_TX) && (*is100MbpsP == TRUE))	{		miiAutoNeg |= MII_ADVR_TX;		if((miiStatus & MII_STAT_TX_FULL_DUPLEX) && (*isFullDuplexP == TRUE))			miiAutoNeg |= MII_ADVR_TX_FULL_DUPLEX;	}	if(miiStatus & MII_STAT_10)	{		miiAutoNeg |= MII_ADVR_10;		if((miiStatus & MII_STAT_10_FULL_DUPLEX) && (*isFullDuplexP == TRUE))			miiAutoNeg |= MII_ADVR_10_FULL_DUPLEX;	}		/* Indicate advertised capabilities */	miiWrite(api_Mac_dev, phyAddr, MII_ADVERTISEMENT, miiAutoNeg);		/* Restart auto-negotiation process */	miiRead(api_Mac_dev, phyAddr, MII_CONTROL, &miiControl);	miiControl |= MII_CTRL_RESTART; 	miiWrite(api_Mac_dev, phyAddr, MII_CONTROL, miiControl);		/* Wait for PHY to auto-negotiate */	if(retries != 0)                     /* If not infinite retries... */		tries = retries;                 /* Initialize attempts remaining */	do	{		miiRead(api_Mac_dev, phyAddr, MII_STATUS, &miiStatus);		if((miiStatus & MII_STAT_REMOTE_FAULT) != 0)		{			status = ERROR;		}		if(retries != 0)                  /* If not infinite retries... */			tries -= 1;                   /* Decrement attempts remaining */	} while((tries != 0) && ((miiStatus & MII_STAT_AUTO_NEG_DONE) == 0));		/* Obtain link partner response */	miiRead(api_Mac_dev, phyAddr, MII_LINK_PARTNER, &miiAutoNeg);//	if((miiAutoNeg & MII_LINK_REMOTE_FAULT) != 0)	if(miiAutoNeg & MII_LINK_REMOTE_FAULT)	{		status = ERROR;    	}		/* Configure PHY for link partner */	miiRead(api_Mac_dev, phyAddr, MII_CONTROL, &miiControl);		/* Select 100 Mbps if this PHY is 100Base-TX capable, the driver asked for	100Mbps and not only 10Mbps, and the link partner responded with	100Base-TX or did not respond at all. The "no response" behavior is	done to allow a wire to be plugged in later and have the PHY negotiate	the best speed. */	if((miiStatus & MII_STAT_TX) && (*is100MbpsP == TRUE) &&	   ((miiAutoNeg & MII_LINK_TX) || (!(miiAutoNeg & MII_LINK_ACK))))	{		miiControl |= MII_CTRL_100MBPS;		*is100MbpsP = TRUE;	}	else            /* Use only 10Mbps, because of options or link partner */	{		miiControl &= (~(MII_CTRL_100MBPS));		*is100MbpsP = FALSE;	}	if((miiAutoNeg & MII_LINK_ACK) && (*isFullDuplexP == TRUE) &&	   (((*is100MbpsP == TRUE) && (miiStatus & MII_STAT_TX_FULL_DUPLEX) &&	   (miiAutoNeg & MII_LINK_TX_FULL_DUPLEX)) ||	   ((*is100MbpsP == FALSE) && (miiStatus & MII_STAT_10_FULL_DUPLEX) &&	   (miiAutoNeg & MII_LINK_10_FULL_DUPLEX))))	{		/* Select full duplex if link partner responded and both the link partner		and this PHY are full duplex capable */		miiControl |= MII_CTRL_FULL_DUPLEX;		*isFullDuplexP = TRUE;	}	else        /* Use only half duplex, because of options or link partner */	{		miiControl &= (~(MII_CTRL_FULL_DUPLEX));		*isFullDuplexP = FALSE;	}	miiWrite(api_Mac_dev, phyAddr, MII_CONTROL, miiControl);	if(tries == 0)	{		status = ERROR;	}    	return status;}#endifint MAC_PHY_INIT(void){//	int 		isFullDuplexP=0; //	int			is100MbpsP=0;	STATUS 		status = OK;	#if 0	if((status = MII_AutoNeg(&api_Mac_dev, 0, &isFullDuplexP, &is100MbpsP)) != OK)	{		printf("ERROR: MII AutoNeg \n");		return status;	}	printf("MII Status Full Duplex=%d, 100Mbps=%d\n", isFullDuplexP, is100MbpsP);#endif	return status;}void api_init(bd_t *bd, API_DEVICE *api_Mac_dev){#ifdef S5N8947_AP	api_Mac_dev->BdmaAddr = BDMA_REG_ADDR_B;	api_Mac_dev->MacAddr = MAC_REG_ADDR_B;	//api_Mac_dev->ivecTx = INT_LVL_ETHTxB;	api_Mac_dev->ivecTx = INT_LVL_MAC_TX;	//api_Mac_dev->ivecRx = INT_LVL_ETHRxB;	api_Mac_dev->ivecRx = INT_LVL_MAC_RX;#else	api_Mac_dev->BdmaAddr = BDMA_REG_ADDR_A;	api_Mac_dev->MacAddr = MAC_REG_ADDR_A;	//api_Mac_dev->ivecTx = INT_LVL_ETHTxA;	api_Mac_dev->ivecTx = INT_LVL_BDMA_TX;	//api_Mac_dev->ivecRx = INT_LVL_ETHRxA;	api_Mac_dev->ivecRx = INT_LVL_BDMA_RX;#endif	/* Set MAC PHY Register */	api_Mac_dev->autoNeg = 0;	api_Mac_dev->netSpeed = 0;	api_Mac_dev->duplexMode = 0;	/* Set Ethernet address *///	SYS_ENET_ADDR_GET(api_Mac_dev, EnetAddrA);	SYS_ENET_ADDR_GET(api_Mac_dev, bd->bi_enetaddr);	api_Mac_dev->channel = 0;}#endif /* COMMANDS & CFG_NET */#endif  /* CONFIG_S5N8947 */

⌨️ 快捷键说明

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