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

📄 dm9kend.c

📁 AT91RM9200 BSP with dual ethernet port
💻 C
📖 第 1 页 / 共 4 页
字号:
    }/********************************************************************************* dm9kMemInit - initialize memory.** Using data in the control structure, setup and initialize the memory* areas needed.  If the memory address is not already specified, then allocate* cache safe memory.** RETURNS: OK or ERROR.*/STATUS dm9kMemInit    (    DM9K_DRV_CTRL * pDrvCtrl /* device to be initialized */    )    {    int         i;      char *      bufPtr;      	        pDrvCtrl->rringSize = DM9K_N_RX_BUF;    pDrvCtrl->tringSize = DM9K_N_TX_BUF;        /* allocate pool structure for mblks, clBlk, and clusters */    if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof(NET_POOL))) == NULL)	return (ERROR);    /* number of clusters is passed in by the endLoadString */    pDrvCtrl->clDesc.clNum    = pDrvCtrl->rringSize * 2;        pDrvCtrl->mClCfg.clBlkNum = pDrvCtrl->clDesc.clNum;    pDrvCtrl->mClCfg.mBlkNum  = pDrvCtrl->mClCfg.clBlkNum * 2;    /* total memory size for mBlks and clBlks */        pDrvCtrl->mClCfg.memSize =        (pDrvCtrl->mClCfg.mBlkNum  *  (MSIZE + sizeof (long))) +        (pDrvCtrl->mClCfg.clBlkNum * (CL_BLK_SZ + sizeof (long)));    /* total memory for mBlks and clBlks */    if ((pDrvCtrl->mClCfg.memArea =         (char *) memalign (sizeof(long), pDrvCtrl->mClCfg.memSize)) == NULL)        return (ERROR);    /* total memory size for all clusters */    pDrvCtrl->clDesc.clSize  = DM9K_BUFSIZ;    pDrvCtrl->clDesc.memSize =        (pDrvCtrl->clDesc.clNum * (pDrvCtrl->clDesc.clSize + 8)) + sizeof(int);    /* Allocate cluster memory */    pDrvCtrl->clDesc.memArea = malloc (pDrvCtrl->clDesc.memSize);    if (pDrvCtrl->clDesc.memArea == NULL)	{	DRV_LOG(DRV_DEBUG_LOAD,		"system memory unavailable\n", 1, 2, 3, 4, 5, 6);	return (ERROR);	}    /* initialize the device net pool */        if (netPoolInit (pDrvCtrl->endObj.pNetPool, &(pDrvCtrl->mClCfg),                     &(pDrvCtrl->clDesc), 1, NULL) == ERROR)        {        DRV_LOG (DRV_DEBUG_LOAD, "Could not init buffering\n",                 1, 2, 3, 4, 5, 6);        return (ERROR);        }        /* Store the cluster pool id as others need it later. */                               if ( ( pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->endObj.pNetPool,                                       DM9K_BUFSIZ, FALSE)) == NULL )        return ERROR;         tableList = cacheDmaMalloc (4 + DM9K_N_RX_BUF*sizeof (dm9kS_TdDescriptor));    tableList= ROUND_UP(tableList,4);    bufPtr = malloc(DM9K_BUFSIZ *(pDrvCtrl->rringSize) + 4);    pDrvCtrl->pRxMemBase = bufPtr;             /* Base address of receive buffers */    /* Initialise tdList descriptor. This descriptor must be WORD aligned*/	for (i = 0; i < pDrvCtrl->rringSize; ++i) 	{				tableList[i].addr = ROUND_UP(bufPtr, 4);		tableList[i].size = 0;		bufPtr+= DM9K_BUFSIZ;	}   		/* Set the WRAP bit at the end of the list descriptor*/	tableList[DM9K_N_RX_BUF-1].addr |= 0x02;			    bufPtr = malloc(DM9K_BUFSIZ * (pDrvCtrl->tringSize) + 4);    pDrvCtrl->pTxMemBase = bufPtr;      for (i = 0; i < pDrvCtrl->tringSize; ++i)	{			pDrvCtrl->pTxMem[i] = ROUND_UP(bufPtr, 4);	bufPtr+= DM9K_BUFSIZ;	}    return (OK);    }void PhyReset( DM9K_DRV_CTRL * pDrvCtrl){	return;}unsigned int PhyStatus( DM9K_DRV_CTRL * pDrvCtrl){	unsigned int Status;	unsigned int r = 0, count=0;	unsigned int i;			return OK;}/******************************************************************** * Name: *	dm9kGetLinkSpeed * Description: *	Link parallel detection status of MAC is checked and set in the *	MAC configuration registers * Arguments: *	pEmac - pointer to MAC * Return value: *	TRUE - if link status set succesfully *	FALSE - if link status not set */// unsigned short aa[26];STATUS dm9kGetLinkSpeed ( DM9K_DRV_CTRL * pDrvCtrl /* device to be initialized */){		return TRUE;	}/********************************************************************************* dm9kStart - start the device** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode.** RETURNS: OK or ERROR*/LOCAL STATUS dm9kStart    (    DM9K_DRV_CTRL * 	pDrvCtrl /* device to be initialized */    ) {    STATUS 		result;    int i;    UINT32 * pReg=NULL;	INT32 status;			    pDrvCtrl->txCleaning = FALSE;    pDrvCtrl->txBlocked  = FALSE;	pDrvCtrl->tmdIndex = 0;	/*set at91rm9200 AIC_SMR[27] mode */	pReg = (UINT32*)0xfffff06c;	*pReg = 0x03;   /*low-level sensitive */	regWriteByte(DM9K_MDWAL,0x0);	regWriteByte(DM9K_MDWAH,0x0);    SYS_INT_CONNECT (pDrvCtrl, dm9kInt, (int)pDrvCtrl, &result);		    DRV_LOG (DRV_DEBUG_LOAD, "Interrupt connected.\n", 1, 2, 3, 4, 5, 6);    if (result == ERROR)        return ERROR;    /* mark the interface as up */    END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));        if(intEnable(DM9K_IRQ)==0);	    DRV_LOG (DRV_DEBUG_LOAD, "interrupt enabled.\n", 1, 2, 3, 4, 5, 6);		/* Activate DM9000A/DM9010 */	regWriteByte(DM9KS_RXCR,0x2f);	/* RX enable */	regWriteByte(DM9KS_IMR, DM9KS_REGFF); 	// Enable TX/RX interrupt mask    return (OK); }/********************************************************************************* dm9kInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.*/ void dm9kInt    ( 		DM9K_DRV_CTRL * 	pDrvCtrl    )    {    	UINT8 reg_save;    	int int_status,i;		reg_save = regReadByte(DM9KS_ADDR_PORT);			/* Disable all interrupt */	regWriteByte(DM9KS_IMR, DM9KS_DISINTR); 		/* Got DM9000A/DM9010 interrupt status */	int_status = regReadByte(DM9KS_ISR);		/* Got ISR */	regWriteByte(DM9KS_ISR, int_status); 	/* Clear ISR status */ 		/* Link status change */	if (int_status & DM9KS_LINK_INTR) 		{			dm9kGetLinkSpeed(pDrvCtrl);//			logMsg("link status change!\n",1,2,3,4,5,6);		}						/* Received the coming packet */	if (int_status & DM9KS_RX_INTR) 		{		netJobAdd ((FUNCPTR)dm9kRecv ,(int)pDrvCtrl, 0, 0, 0, 0);		}		/* Trnasmit Interrupt check */	if (int_status & DM9KS_TX_INTR)		          /* maybe should be modified */		{		DRV_LOG(DRV_DEBUG_TX,"packet transmitted!\n",1,2,3,4,5,6);		pDrvCtrl->tmdLastIndex = (pDrvCtrl->tmdLastIndex + 1) &					 (pDrvCtrl->tringSize - 1);		}	if (pDrvCtrl->txBlocked == TRUE)        {        DRV_LOG(DRV_DEBUG_TX,"packet blocked!\n",1,2,3,4,5,6);        pDrvCtrl->txBlocked = FALSE;        netJobAdd ((FUNCPTR)muxTxRestart, (int)&pDrvCtrl->endObj, 0, 0, 0, 0);        }        		/* Re-enable interrupt mask */ 		regWriteByte(DM9KS_IMR, DM9KS_REGFF);					/* Restore previous register address */	writeWord(reg_save);	return;            }/********************************************************************************* dm9kRecv - process the next incoming packet** RETURNS: OK/ERROR*/LOCAL STATUS dm9kRecv    (    DM9K_DRV_CTRL *	pDrvCtrl /* device to be initialized */    )    {    int			len;    M_BLK_ID	pMblk;    char *		pCluster;    char *		pBuf;    CL_BLK_ID	pClBlk;    int			lineCount,residual,rmdIndex;    int		oldlevel;	/* current interrupt level mask */    int i,j;	UINT16 MDRAH,MDRAL,tmplen;	UINT8 rxbyte;	rx_t rx;	UINT16 * ptr = (UINT16*)&rx;	UINT8* rdptr;	BOOL GoodPacket;do{	/*store the value of Memory Data Read address register*/	MDRAH=regReadByte(DM9KS_MDRAH);	MDRAL=regReadByte(DM9KS_MDRAL);				/* Dummy read */	regReadByte(DM9KS_MRCMDX);		/*	 * Read the rx indication. Note that the implicit u8 cast 	 * actually get the first byte of RX SRAM	*/		rxbyte = IN_WORD(DM9KS_DATA_PORT);	/* Got most updated data */			/* packet ready to receive check */		if(rxbyte != 0x01) break;			/* A packet ready now  & Get status/length */		GoodPacket = TRUE;					OUT_WORD(DM9KS_ADDR_PORT, DM9KS_MRCMD);    /* Select MRCMD to enable address increment (by HL) */			/* Read packet status & length */		*ptr = IN_WORD(DM9KS_DATA_PORT);		*(ptr+1) = IN_WORD(DM9KS_DATA_PORT);	/* already bswap by hw */				/* Packet status check */		if (rx.desc.status & 0xbf)		{			GoodPacket = FALSE;			if (rx.desc.status & 0x01) 			{				DRV_LOG (DRV_DEBUG_LOAD, "<RX FIFO error>\n", 1, 2, 3, 4, 5, 6);							}			if (rx.desc.status & 0x02) 			{				DRV_LOG (DRV_DEBUG_LOAD, "<RX CRC error>\n", 1, 2, 3, 4, 5, 6);							}			if (rx.desc.status & 0x80) 			{				DRV_LOG (DRV_DEBUG_LOAD, "<RX Length error>\n", 1, 2, 3, 4, 5, 6);							}			if (rx.desc.status & 0x08)			DRV_LOG (DRV_DEBUG_LOAD, "<Physical Layer error>\n", 1, 2, 3, 4, 5, 6);					}		if (!GoodPacket)		{			// drop this packet!!!			tmplen = (rx.desc.length + 1) / 2;			DRV_LOG (DRV_DEBUG_LOAD, "drop this packet!\n", 1, 2, 3, 4, 5, 6);  						for (i = 0; i < tmplen; i++) 			{				IN_WORD(DM9KS_DATA_PORT);			}			continue;		}	len = rx.desc.length;	pBuf = (char *)pDrvCtrl->pRxMemBase;    if (pBuf == NULL )		{				DRV_LOG (DRV_DEBUG_LOAD, "KERN_WARNING: Memory squeeze.\n", 1, 2, 3, 4, 5, 6);						/*re-load the value into Memory data read address register*/			regWriteByte(DM9KS_MDRAH,MDRAH);			regWriteByte(DM9KS_MDRAL,MDRAL);			return;		}		else		{						/* Read received packet from RX SARM */			tmplen = (rx.desc.length + 1) / 2;			for (i = 0; i < tmplen; i++) 			{				((UINT16 *)pBuf)[i] = IN_WORD(DM9KS_DATA_PORT);							}		}   	    /* If error flag OR if packet is not completely in one buffer */    if (!len)	{		DRV_LOG (DRV_DEBUG_RX, "RMD error!\n", 1, 2, 3, 4, 5, 6);		END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);		goto cleanRXD;				/* skip to clean up */	}       /* If we cannot get a buffer to loan then bail out. */    pCluster = netClusterGet (pDrvCtrl->endObj.pNetPool,			      pDrvCtrl->pClPoolId);    if (pCluster == NULL)	{		DRV_LOG (DRV_DEBUG_RX, "Cannot loan!\n", 1, 2, 3, 4, 5, 6);		END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        	pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;        	muxError(&pDrvCtrl->endObj, &pDrvCtrl->lastError);		goto cleanRXD;	}    if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL)	{		netClFree (pDrvCtrl->endObj.pNetPool, pCluster);			DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6);		END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        	pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;        	muxError(&pDrvCtrl->endObj, &pDrvCtrl->lastError);		goto cleanRXD;	}    /*     * OK we've got a spare, let's get an M_BLK_ID and marry it to the     * one in the ring.     */    if ((pMblk = mBlkGet(pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA))	== NULL)	{	netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk);	netClFree (pDrvCtrl->endObj.pNetPool, pCluster);	DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6);	END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        pDrvCtrl->lastError.errCode = END_ERR_NO_BUF;        muxError(&pDrvCtrl->endObj, &pDrvCtrl->lastError);	goto cleanRXD;	}    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);	CACHE_DMA_INVALIDATE(pCluster + pDrvCtrl->offset, len);    bcopy (pBuf, pCluster + pDrvCtrl->offset, len);                  /* offset must be 0x02 to align */	CACHE_DMA_FLUSH(pCluster + pDrvCtrl->offset, len);    /* Join the cluster to the MBlock */    netClBlkJoin (pClBlk, pCluster, len, NULL, 0, 0, 0);    netMblkClJoin (pMblk, pClBlk);    pMblk->mBlkHdr.mData  += pDrvCtrl->offset;    pMblk->mBlkHdr.mLen	  = len;    pMblk->mBlkHdr.mFlags |= M_PKTHDR;    pMblk->mBlkPktHdr.len = len;	    /* Advance our management index */		    /* Call the upper layer's receive routine. */    END_RCV_RTN_CALL(&pDrvCtrl->endObj, pMblk);         return (OK); }while((rxbyte & 0x01) == DM9KS_PKT_RDY);cleanRXD:    DRV_LOG (DRV_DEBUG_RX, "cleanRXD....dm9kRecv clean index\n",	     0, 0, 0, 0, 0, 0);   return (OK);     }/********************************************************************************* dm9kSend - the driver send routine** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it.  This is done by a higher layer.  The last arguments are a free* routine to be called when the device is done with the buffer and a pointer* to the argument to pass to the free routine.  ** RETURNS: OK or ERROR.*/

⌨️ 快捷键说明

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