📄 sngks32cend.c
字号:
#if 0/***************************************************************************** * at91cEndBdmaTxInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the BdmaTx controller.** RETURNS: N/A.*/LOCAL void at91cEndBdmaTxInt ( END_DEVICE *pDrvCtrl /* interrupting device */ ) { /**Nothing to be done here**/ }#endif/******************************************************************************* at91cEndBdmaRxInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the BdmaTx controller.** RETURNS: N/A.*/LOCAL void at91cEndMacRxInt ( END_DEVICE *pDrvCtrl /* interrupting device */ ) { #if 1 RECEIVE_BUF_DESC * pReceiveBufDesc; UCHAR current; *(volatile UINT32 *)AT91C_EMAC_RSR=0xfff; pReceiveBufDesc=pDrvCtrl->pRxBufDesc; current = pDrvCtrl->tail; do { if(pReceiveBufDesc[current].w0.ownerShip == OWNED_BY_CPU) { /* logMsg("process id:%d\n",current,2,3,4,5,6);*/ netJobAdd ((FUNCPTR)at91cEndRecv, (int)pDrvCtrl, (int) &pReceiveBufDesc[current],0,0,0); /* if (!pDrvCtrl->rxHandling && !pDrvCtrl->resetting) { pDrvCtrl->rxHandling = TRUE; }*/ } current=((current+1)%RX_FD_NUM); } while(&pReceiveBufDesc[current]!=*(volatile UINT32 *)AT91C_EMAC_RBQP); pDrvCtrl->tail=current;#endif#if 0 RECEIVE_BUF_DESC * pReceiveBufDesc; int i; /* RECEIVE_BUF_DESC *p; p=*(volatile UINT32 *)AT91C_EMAC_RBQP;*/ *(volatile UINT32 *)AT91C_EMAC_RSR=0xfff; pReceiveBufDesc=pDrvCtrl->pRxBufDesc; #if 0 if(p->w0.ownerShip == OWNED_BY_CPU)/*当前buf 必须处理*/ { at91cEndRecv((int)pDrvCtrl,(int)p); }#endif for(i=0;i<64;i++) { if(pReceiveBufDesc[i].w0.ownerShip == OWNED_BY_CPU) {/* logMsg("id%d\n",i,2,3,4,5,6); */ netJobAdd ((FUNCPTR)at91cEndRecv, (int)pDrvCtrl, (int) &pReceiveBufDesc[i],0,0,0); } /* if(&pReceiveBufDesc[i]==(int)(*(volatile UINT32 *)AT91C_EMAC_RBQP))break;*/ }#endif }/******************************************************************************* at91cEndMacTxInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the MacRx controller.** RETURNS: N/A.*/LOCAL void at91cEndMacTxInt ( END_DEVICE *pDrvCtrl /* interrupting device */ ) {#if 1 UINT32 stat; if(pDrvCtrl->pTxBufDesc->head != pDrvCtrl->pTxBufDesc->tail) { stat = *(volatile UINT32 *)AT91C_EMAC_TSR; if(!(stat & AT91C_EMAC_BNQ)) return; /* *(volatile UINT32 *)AT91C_EMAC_TSR |= AT91C_EMAC_COMP;*/ *(volatile UINT32 *)AT91C_EMAC_TSR = stat; *(volatile UINT32 *)(AT91C_EMAC_TAR) = pDrvCtrl->pTxBufDesc->transBufFd[pDrvCtrl->pTxBufDesc->head].transBufPtr; *(volatile UINT32 *)(AT91C_EMAC_TCR) = pDrvCtrl->pTxBufDesc->transBufFd[pDrvCtrl->pTxBufDesc->head].length;/* *(volatile UINT32 *)AT91C_EMAC_CTL |= AT91C_EMAC_TE; logMsg("head:%d,addr = %x,len=%d\n",pDrvCtrl->pTxBufDesc->head,*(volatile UINT32 *)(AT91C_EMAC_TAR), pDrvCtrl->pTxBufDesc->transBufFd[pDrvCtrl->pTxBufDesc->head].length,0,0,0); */ pDrvCtrl->pTxBufDesc->head = ((pDrvCtrl->pTxBufDesc->head +1) % TX_FD_NUM); } else { firstSend=1; pDrvCtrl->pTxBufDesc->tail =pDrvCtrl->pTxBufDesc->head=0; } #endif/* END_TX_SEM_GIVE (&pDrvCtrl->end);*//*防止多次进入发送?*//*可以添加发送统计寄存器计数*/ }#if 0/******************************************************************************* at91cEndMacRxInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the MacRx controller.** RETURNS: N/A.*/LOCAL void at91cEndMacRxInt ( END_DEVICE *pDrvCtrl /* interrupting device */ ) { /***Nothing to be done here***/ }#endif/******************************************************************************* at91cEndMacRxInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the EMAC controller.** RETURNS: N/A.*/LOCAL void at91cEndInt ( END_DEVICE *pDrvCtrl /* interrupting device */ ) { UINT32 stat1,stat2;/* logMsg("get into int\n",0,0,0,0,0,0); */ stat1 = *(volatile UINT32 *)AT91C_EMAC_ISR; stat2= ~*(volatile UINT32 *)AT91C_EMAC_IMR; stat1 &= stat2;/* logMsg("stat1= %x stat2= %x \n",stat1,stat2,0,0,0,0); */ if(stat1 & AT91C_EMAC_RCOM ) at91cEndMacRxInt(pDrvCtrl); if(stat1 & AT91C_EMAC_TCOM) at91cEndMacTxInt(pDrvCtrl); } /******************************************************************************** at91cEndHandleRcvInt - task level interrupt service for input packets** This routine is called at task level indirectly by the interrupt* service routine to do any message received processing.** RETURNS: N/A.*/LOCAL void at91cEndHandleRcvInt ( END_DEVICE *pDrvCtrl /* interrupting device */ ) { }/******************************************************************************** at91cEndRecv - process the next incoming packet** Handle one incoming packet. The packet is checked for errors.** RETURNS: N/A.*/LOCAL STATUS at91cEndRecv ( END_DEVICE *pDrvCtrl, /* device structure */ RECEIVE_BUF_DESC *pRxD /* frame descriptor */ ) { M_BLK_ID pMblk = NULL; char *pNewCluster = NULL; CL_BLK_ID pClBlk = NULL; char *pData; UINT32 len = pRxD->w1.frameLength; char *ptr; int i; /*为了对齐,收到数据往后搬迁2个byte*/ i=len; pData=(char *)(((UINT32)pRxD->w0.baseAddrRecBuf)<<2); ptr=(char *)(pData+len); while(i-->0) { *(ptr+1)=*(ptr-1); ptr--; }#if 0 *(volatile UINT32 *)AT91C_EMAC_RBQP= pDrvCtrl->pRxBufDesc;/*添加*/ pDrvCtrl->tail ++;/*防止跑飞*/ if(pDrvCtrl->tail==63) { pDrvCtrl->tail=0; *(volatile UINT32 *)AT91C_EMAC_RBQP= pDrvCtrl->pRxBufDesc; }#endif /* logMsg("address =%08x,length=%d\n",pData,len,3,4,5,6); */ if (pDrvCtrl->end.pNetPool == NULL) { DRV_LOG (DRV_DEBUG_RX, "at91cEndRecv: Illegal pNetPool on entry!\n", 0,0,0,0,0,0); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; } /* Add one to our unicast data. */ END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1); if ((pMblk = mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL) { DRV_LOG (DRV_DEBUG_RX, "at91cEndRecv: Out of M Blocks!\n", 0,0,0,0,0,0); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; } pNewCluster = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->end.pNetPool->clTbl[0]); if (pNewCluster == NULL) { DRV_LOG (DRV_DEBUG_RX, "at91cEndRecv: Cannot loan!\n", 0,0,0,0,0,0); pDrvCtrl->lastError.errCode = END_ERR_NO_BUF; muxError(&pDrvCtrl->end, &pDrvCtrl->lastError); goto cleanRXD; } /* Grab a cluster block to marry to the cluster we received. */ if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL) { DRV_LOG (DRV_DEBUG_RX, "at91cEndRecv: Out of Cluster Blocks!\n", 0,0,0,0,0,0); pDrvCtrl->lastError.errCode = END_ERR_NO_BUF; muxError(&pDrvCtrl->end, &pDrvCtrl->lastError); goto cleanRXD; } END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);/*非cache 的使用 pData = END_CACHE_PHYS_TO_VIRT(pData);*/ /* Note: we rely on the hardware to pad 2 bytes so we don't need to copy to * a new buffer to solve alignment problems */ /* Join the cluster to the MBlock */ if (netClBlkJoin (pClBlk, pData, AT91C_CL_SIZE, NULL, 0, 0, 0) == NULL) { DRV_LOG (DRV_DEBUG_RX, "at91cEndRecv: netClBlkJoin failed\n", 0,0,0,0,0,0); pDrvCtrl->lastError.errCode = END_ERR_NO_BUF; muxError(&pDrvCtrl->end, &pDrvCtrl->lastError); goto cleanRXD; } if (netMblkClJoin (pMblk, pClBlk) == NULL) { DRV_LOG (DRV_DEBUG_RX, "at91cEndRecv: netMblkClJoin failed\n", 0,0,0,0,0,0); pDrvCtrl->lastError.errCode = END_ERR_NO_BUF; muxError(&pDrvCtrl->end, &pDrvCtrl->lastError); goto cleanRXD; } /* The ip structure is 14 bytes from the beginning of the valid frame data * yet it must be aligned on a word boundary. We have told the ethernet * controller to insert 2 bytes of garbage at the beginning of each frame * so now all we need to do is move our pointer to the frame data to the * real start of the frame causing the frame to be half-word aligned but * not word aligned. By counting 14 bytes from the beginning of the frame * to the ip, we arrive on a word boundary. */ pMblk->mBlkHdr.mData += AT91C_DATA_OFFSET; pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkHdr.mLen = len; pMblk->mBlkPktHdr.len = len; /* Call the upper layer's receive routine. */ END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk); pRxD->w0.baseAddrRecBuf = ((UINT32)pNewCluster)>>2; pRxD->w0.ownerShip=0; return (OK);cleanRXD: if (pClBlk != NULL) { netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk); } if (pNewCluster != NULL) { netClFree (pDrvCtrl->end.pNetPool, pNewCluster); pNewCluster = NULL; } if (pMblk != NULL) { netMblkFree (pDrvCtrl->end.pNetPool, pMblk); } END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); return (ERROR); }/******************************************************************************** at91cEndSend - 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.*/LOCAL STATUS at91cEndSend ( END_DEVICE *pDrvCtrl, /* device ptr */ M_BLK_ID pNBuff /* data to send */ ) { int len; int oldLevel; UCHAR *pTx; UINT32 stat; if (pDrvCtrl->resetting) { return ERROR; }if(((pDrvCtrl->pTxBufDesc->tail + 1)%TX_FD_NUM) != pDrvCtrl->pTxBufDesc->head) { END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER); pTx = pDrvCtrl->pTxBufDesc->transBufFd[pDrvCtrl->pTxBufDesc->tail].transBufPtr; /* * Obtain exclusive access to transmitter. This is necessary because * we might have more than one stack transmitting at once. */ /* Set pointers in local structures to point to data. */ len = netMblkToBufCopy(pNBuff, (void *)pTx, NULL) ; if(firstSend==1/*first */) { firstSend=0; pDrvCtrl->pTxBufDesc->tail=pDrvCtrl->pTxBufDesc->head=0; stat = *(volatile UINT32 *)AT91C_EMAC_TSR; if (!(stat & AT91C_EMAC_BNQ)) return ERROR;/* printf("send ptr=%08x,length=%d\n",pTx,len); */ *(volatile UINT32 *)AT91C_EMAC_TSR = stat;/* Reset stat word */ /* place a transmit request */ oldLevel = intLock (); /* now at91cEndInt won't get confused */ /* initiate device transmit *//* logMsg("tar = %x \n",pTx,0,0,0,0,0); */ *(volatile UINT32 *)(AT91C_EMAC_TAR) = pTx;/* logMsg("addr = %x \n",*(volatile UINT32 *)(AT91C_EMAC_TAR),0,0,0,0,0);*/ *(volatile UINT32 *)(AT91C_EMAC_TCR) = len; *(volatile UINT32 *)AT91C_EMAC_CTL |= AT91C_EMAC_TE; intUnlock (oldLevel); /* now at91cEndInt won't get confused */ pDrvCtrl->pTxBufDesc->transBufFd[pDrvCtrl->pTxBufDesc->tail].length = len;/* logMsg("addr = %x,len=%d,tain=%d\n",pDrvCtrl->pTxBufDesc->transBufFd[pDrvCtrl->pTxBufDesc->tail].transBufPtr, len,pDrvCtrl->pTxBufDesc->tail,4,5,6); *//* while(((*(volatile UINT32 *)AT91C_EMAC_TSR)&AT91C_EMAC_BNQ)==0);*/ pDrvCtrl->pTxBufDesc->tail = ((pDrvCtrl->pTxBufDesc->tail +1) % TX_FD_NUM); pDrvCtrl->pTxBufDesc->head = ((pDrvCtrl->pTxBufDesc->head +1) % TX_FD_NUM); } else { pDrvCtrl->pTxBufDesc->transBufFd[pDrvCtrl->pTxBufDesc->tail].length = len;/* logMsg("addr = %x,len=%d,tain=%d\n",pDrvCtrl->pTxBufDesc->transBufFd[pDrvCtrl->pTxBufDesc->tail].transBufPtr, len,pDrvCtrl->pTxBufDesc->tail,4,5,6); */ pDrvCtrl->pTxBufDesc->tail =((pDrvCtrl->pTxBufDesc->tail + 1) % TX_FD_NUM); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -