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

📄 sngks32cend.c.bak

📁 vxworks BSP AT91RM9200 网卡驱动,串口驱动
💻 BAK
📖 第 1 页 / 共 5 页
字号:
/******************************************************************************* at91cEndMCastGet - 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 at91cEndMCastGet    (    END_DEVICE* pDrvCtrl,    /* device pointer */    MULTI_TABLE* pTable        /* address table to be filled in */    )    {    int error;    error = etherMultiGet (&pDrvCtrl->end.multiList, pTable);    return (error);    }/******************************************************************************** at91cEndStop - 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 at91cEndStop    (    END_DEVICE *pDrvCtrl    /* device to be stopped */    )    {    STATUS result = OK;    *(volatile UINT32 *)AT91C_EMAC_CTL &= ~(AT91C_EMAC_RE | AT91C_EMAC_TE);	    intDisable (pDrvCtrl->ivecEMAC);    END_FLAGS_CLR (&pDrvCtrl->end, IFF_UP | IFF_RUNNING);    return (result);    }/******************************************************************************* at91cEndReset - Reset the device* This function resets the driver after initializing from at91cEndLoad*/LOCAL void    at91cEndReset    (    END_DEVICE* pDrvCtrl    /* device to be reset */    )    {    	UINT32 stat1, stat2;	char lab=0;  	    if(pDrvCtrl->unit != 0)        return;		/* set LED 1 is active status, and LED 2 is link status */		at91cEndPhyWrite (PHY_LED_CFG, PHY_ADDR, 0x24f2/*0x74f2*/);				/* set PHY is 100MBPS & FullDuplex */		at91cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _100_MB_FDX);		    if (pDrvCtrl->autoNeg == 1) /* auto negotiation enabled */     {        		/*at91cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _AUTO_NEGOTIATE);   		while(!(at91cEndPhyRead(PHY_STS1_REG,PHY_ADDR)& (1<<5)));*/		stat1 = at91cEndPhyRead(PHY_STS1_REG,PHY_ADDR);		if(!(stat1 & 0x4))			{				    			return;	/* no link */		}				stat2 = at91cEndPhyRead(PHY_STS2_REG,PHY_ADDR);				if ((stat1 & 0x4000) && (stat2 & 0x8000) ) 		/*set RMII for 100BaseTX and Full Duplex*/		{			lab = 'A';	    	}    		else if ((stat1 & 0x2000) && (stat2 & 0x4000))    /*set MII for 100BaseTX and Half Duplex */		{			lab = 'B';	    	}    		else if ((stat1 & 0x1000) && (stat2 & 0x2000))     /*set MII for 10BaseT and Full Duplex */		{			lab = 'C';	    	}    		else if ((stat1 & 0x0800) && (stat2 & 0x1000))     /*set MII for 10BaseT and Half Duplex */		{			lab = 'D';		}	    	}    else if (pDrvCtrl->netSpeed == 10)    {    	    	if (pDrvCtrl->duplexMode == 1)    /* FDX */        	    	{	    		at91cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _10_MB_FDX);					lab = 'C';    	    	}		else				{	           	at91cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _10_MB_HDX);					lab = 'D';	    	}	    }	    else if (pDrvCtrl->netSpeed == 100)    {	        if (pDrvCtrl->duplexMode == 1)    /* FDX */	        {	        	at91cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _100_MB_FDX);			lab = 'A';	        }	        else	        {	            	at91cEndPhyWrite (PHY_CONTROL_REG, PHY_ADDR, _100_MB_HDX);			lab = 'B';	        }    }	lab = 'A';	switch(lab)	{		case 'A':    			*(volatile UINT32 *)AT91C_EMAC_CFG |= AT91C_EMAC_SPD| AT91C_EMAC_FD;		break;		case 'B':			*(volatile UINT32 *)AT91C_EMAC_CFG |= AT91C_EMAC_SPD;			*(volatile UINT32 *)AT91C_EMAC_CFG &=	~AT91C_EMAC_FD;		break;		case 'C':			*(volatile UINT32 *)AT91C_EMAC_CFG &=	~AT91C_EMAC_SPD;			*(volatile UINT32 *)AT91C_EMAC_CFG |= AT91C_EMAC_FD;		break;		case 'D':			*(volatile UINT32 *)AT91C_EMAC_CFG &= ~(AT91C_EMAC_SPD| AT91C_EMAC_FD);		break;		default :		break;	}   *(volatile UINT32 *)AT91C_EMAC_CTL |= AT91C_EMAC_CSR;   /*clear the statistic regs*/   *(volatile UINT32 *)AT91C_EMAC_CTL = 0;   *(volatile UINT32 *)AT91C_EMAC_TSR= 0;   *(volatile UINT32 *)AT91C_EMAC_RSR= 0;  /* *(volatile UINT32 *)AT91C_EMAC_CFG |= (AT91C_EMAC_RMII |AT91C_EMAC_CAF);*//*   *(volatile UINT32 *)AT91C_EMAC_CFG |= (AT91C_EMAC_RMII );*/    return;    }#undef DYNAMIC_PHY/******************************************************************************* at91cEndPhyRead - Read PHY device* This function is used to read a byte from the PHY device*/UINT32 at91cEndPhyRead    (    UINT32 phyRegAddr, /* Address of PHY register to be read */    UINT32 phyAddr     /* Address of the PHY chip (usually 0 for single PHY) */    )    {    UINT32 phyData;    *(volatile UINT32 *)AT91C_EMAC_CTL |= AT91C_EMAC_MPE; /*Management Port Enable */    *(volatile UINT32 *)AT91C_EMAC_MAN  = AT91C_EMAC_CODE |AT91C_EMAC_RD |AT91C_EMAC_HIGH 									| phyRegAddr << 18 |phyAddr <<23;    while ( (*(volatile UINT32 *)AT91C_EMAC_SR & 0x4) == 0) /***** IDLE bit ******/        ;    /* Wait till IDLE bit is SET */    phyData = *(volatile UINT32*)AT91C_EMAC_MAN & AT91C_EMAC_DATA ;   *(volatile UINT32 *)AT91C_EMAC_CTL &= ~AT91C_EMAC_MPE; /*Management Port disable */	    return (phyData);    } /*DYNAMIC_PHY*//******************************************************************************* at91cEndPhyWrite    - Write into PHY device* This function is used to write a byte to the PHY device*/void at91cEndPhyWrite    (    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 */    )    {  /*  UINT32 count = 1000;*/    *(volatile UINT32 *)AT91C_EMAC_CTL |= AT91C_EMAC_MPE; /*Management Port Enable */    *(volatile UINT32 *)AT91C_EMAC_MAN  = AT91C_EMAC_CODE |AT91C_EMAC_WR |AT91C_EMAC_HIGH 									| phyRegAddr << 18 |phyAddr <<23 | phyData ;    while ( (*(volatile UINT32 *)AT91C_EMAC_SR & 0x4) == 0) /***** IDLE bit ******/        ;    /* Wait till IDLE bit is SET *//*    while (count--)        ;  */  /* Dummy delay after PHY write */   *(volatile UINT32 *)AT91C_EMAC_CTL &= ~AT91C_EMAC_MPE; /*Management Port disable */	    }/******************************************************************************* at91cEndMacIntialize - Initialize MAC/BDMA registers* Initialize the MAC and BDMA registers to make the Ethernet* interface functional*/LOCAL void at91cEndMacInitialize    (    END_DEVICE *pDrvCtrl    /* Device that has to be initialized */    )    {    UCHAR    *pAddr;  /* UINT32 temp;     UINT32 * SAH;    UINT32 *SAL;    UCHAR count;	*/	#if 1#if (_BYTE_ORDER != _LITTLE_ENDIAN)    UCHAR *pEnetAddr;#endif#endif#if 1    /* Copy our MAC address to the first location in address array */    pAddr = (UCHAR *)(&(pDrvCtrl->addrList[0]));#if (_BYTE_ORDER == _LITTLE_ENDIAN)    *(UINT32 *)pAddr = htonl (*(UINT32 *)pDrvCtrl->enetAddr);    pAddr += 6;    *(UINT16 *)pAddr = htons (*(UINT16 *)(pDrvCtrl->enetAddr+4));#else /* (_BYTE_ORDER == _LITTLE_ENDIAN) */    /* big endian: no need to swap */    for (pEnetAddr=pDrvCtrl->enetAddr;         pEnetAddr<pDrvCtrl->enetAddr+6;         pEnetAddr++)        {        *pAddr++ = *pEnetAddr;        }#endif /* (_BYTE_ORDER == _LITTLE_ENDIAN) */#endif    /* Copy the address array into Specific registers *//*MAC地址--写入特殊地址*/#if 1/*网络顺序	[7-0, ... ,47-40] mac[]={ 0x00, 0xA0, 0x88, 0x88, 0x88, 0x00 }	7-0*/*(volatile UINT32 *) AT91C_EMAC_SA1L = 0x88888800;*(volatile UINT32 *) AT91C_EMAC_SA1H = 0x88;#endif/* receive all packets */    if (END_FLAGS_GET(&pDrvCtrl->end) & IFF_PROMISC)	    *(volatile UINT32 *)AT91C_EMAC_CFG |= AT91C_EMAC_CAF;    /* INT trans buf empty  enable */    if ((pDrvCtrl->flags & LS_POLLING) == 0)    /* Not polling mode */{	    *(volatile UINT32 *)AT91C_EMAC_IER = AT91C_EMAC_TCOM; 	firstSend = 1;}    return;    }/*******************************************************************************    at91cEndFdInitialize - Initialize TX and RX FD lists*    Make a circular list of Rx and TX frame descriptors and buffers.*    pDrvCtrl->pRxBufDesc and pDrvCtrl->pTxBufDesc *    store 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 at91cEndFdInitialize    (    END_DEVICE* pDrvCtrl    /* device to be initialized */    )    {    int count;    RECEIVE_BUF_DESC*      pReceiveBufDesc;    char                    *pNewCluster;   	pDrvCtrl->pTxBufDesc =cacheDmaMalloc(sizeof(TRANSMIT_BUF_DESC));	pDrvCtrl->pTxBufDesc->head = 0;	pDrvCtrl->pTxBufDesc->tail = 0;			    for(count = 0; count < TX_FD_NUM; count++)    {		pDrvCtrl->pTxBufDesc->transBufFd[count].transBufPtr = (UINT32)calloc(END_BUFSIZ,1);		/*printf("add%d = %x\n",count,pDrvCtrl->pTxBufDesc->transBufFd[count].transBufPtr);*/    }/*11. EMAC: Using Receive frames and buffers not word-alignedA dead lock may appear when the Ethernet MAC attempts to store a new receivedvalid frame while there are no more rx buffer descriptors. This appears only whenthe received frame length is not a multiple of 4 bytes. In this configuration, even ifthe application enables new receive buffer descriptors, all packets will be rejected.Problem Fix/WorkaroundThe software workaround is to disable and re-enable the receive function in the networkfunction register ETH_CTL each time a buffer is not available (RBNA in thestatus register).ETH CTL &= ~0x00000004 ;ETH CTL |= 0x00000004 ;Note that an interrupt can be activated for the RBNA detection.Another workaround is to align the address of the receive buffer descriptor on aboundary of 16 Words (address 0xaaaa aa00, 0xaaaa aa40, 0xaaaa aa80,.....)*//*bug fix	硬件系统bug*/if ((pReceiveBufDesc =         (RECEIVE_BUF_DESC *)memalign(0x1000,RX_FD_NUM*sizeof(RECEIVE_BUF_DESC)))        == NULL)        {        return ERROR;        }    vmStateSet(NULL,pReceiveBufDesc,4096,VM_STATE_MASK_BUFFERABLE|VM_STATE_MASK_CACHEABLE|					VM_STATE_MASK_VALID|VM_STATE_MASK_WRITABLE,VM_STATE_BUFFERABLE_NOT|			VM_STATE_CACHEABLE_NOT|VM_STATE_VALID|VM_STATE_WRITABLE);			/*        pReceiveBufDesc = END_CACHE_VIRT_TO_PHYS(pReceiveBufDesc);*//*            pReceiveBufDesc &= ~0x03; */                 pDrvCtrl->pRxBufDesc = (RECEIVE_BUF_DESC *)pReceiveBufDesc;         /* Initialize the register */         *(volatile UINT32 *)(AT91C_EMAC_RBQP) = (UINT32)pReceiveBufDesc;		    for(count = 0; count < RX_FD_NUM; count++)        {	        if (pDrvCtrl->end.pNetPool == NULL ||	            pDrvCtrl->end.pNetPool->clTbl[0] == 0)	            {	            return ERROR;	            }	        pNewCluster = netClusterGet (pDrvCtrl->end.pNetPool,	                                     pDrvCtrl->end.pNetPool->clTbl[0]);	        if (pNewCluster == NULL)	            {	            pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;	            muxError(&pDrvCtrl->end, &pDrvCtrl->lastError);	            return ERROR;	            }	/*        pNewCluster = END_CACHE_VIRT_TO_PHYS(pNewCluster);*/			    pReceiveBufDesc->w0.baseAddrRecBuf = ((UINT32)pNewCluster)>>2; 	    pReceiveBufDesc->w0.ownerShip = OWNED_BY_DMA;	            /*set wrap bit*/		if (count == (RX_FD_NUM - 1))	            (pReceiveBufDesc->w0).wrap = 1;		else		     (pReceiveBufDesc->w0).wrap = 0;	        pReceiveBufDesc++;		        }/* end of for loop*/    pDrvCtrl->fdInitialized = TRUE;    return OK;    }/*******************************************************************************    at91cEndFdFree - 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 at91cEndFdFree    (    END_DEVICE* pDrvCtrl    /* device to be freed */    )    {    RECEIVE_BUF_DESC *pReceiveBufDesc;    UINT32 count;    if (pDrvCtrl->fdInitialized == FALSE)        return;#if 1    for (count = 0; count < TX_FD_NUM; count++)    {		free((void *)pDrvCtrl->pTxBufDesc->transBufFd[count].transBufPtr);		    }    free((void *)pDrvCtrl->pTxBufDesc);#endif    pReceiveBufDesc = (RECEIVE_BUF_DESC*)pDrvCtrl->pRxBufDesc;    for (count = 0; count < RX_FD_NUM; count++)        {		if(((UINT32)pReceiveBufDesc->w0.baseAddrRecBuf)<<2)		{		/*	pReceiveBufDesc->w0.baseAddrRecBuf	END_CACHE_PHYS_TO_VIRT*/			netClFree(pDrvCtrl->end.pNetPool,				(char*)((UINT32)((char *)pReceiveBufDesc->w0.baseAddrRecBuf)<<2));/*			(char *)(((UINT32)pReceiveBufDesc->w0.baseAddrRecBuf)<<2) = (UINT32)NULL;*/		}		pReceiveBufDesc++;  	                }/*     END_CACHE_PHYS_TO_VIRT(;*/     free(pDrvCtrl->pRxBufDesc);       	    pDrvCtrl->fdInitialized = FALSE;    }/******************************************************************************* at91cEndPIOConfig-config PIO Pins used by EMAC */LOCAL void at91cEndPIOConfig(){	/* enable mac clock */	*(volatile UINT32 *)AT91C_PMC_PCER = 0x01000000;/*  (PIOA) PIO Disable Register	*/	*(volatile UINT32 *)AT91C_PIOA_PDR = AT91C_PIO_PA7  | AT91C_PIO_PA8   | AT91C_PIO_PA9   | AT91C_PIO_PA10									| AT91C_PIO_PA11 | AT91C_PIO_PA12 | AT91C_PIO_PA13 | AT91C_PIO_PA14		

⌨️ 快捷键说明

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