📄 wancomend.c
字号:
pTxDescLast = pTxDescCurr; /* In case of multiple clusters per packet */ while ( pTuple != NULL && pTuple->mBlkHdr.mLen != 0 ) { WANCOM_DRV_LOG (DRV_DEBUG_TX, ("Tx process tuple 0x%x in packet 0x%x \n"), (UINT32)pTuple, (UINT32)pMblk, 0, 0, 0, 0); if ( firstDesc ) { firstDesc = FALSE; pTxDescCurr->cmd_sts = FIRST | PADDING | GENERATE_CRC; } else pTxDescCurr->cmd_sts = OWNER_BY_GT | PADDING | GENERATE_CRC; pTxDescCurr->bytecnt = pTuple->mBlkHdr.mLen; pTxDescCurr->shadow = 0x5432; /* buffers with a payload smaller than 8 bytes must be aligned */ /* to 64-bit boundary. We use the memory allocated for the Tx */ /* descriptor. This memory located in TX_BUF_OFFSET_IN_DESC */ /* offset within the Tx descriptor. */ if ( pTxDescCurr->bytecnt <= 8 ) { pTxDescCurr->buf_ptr = (UINT32)pTxDescCurr + TX_BUF_OFFSET_IN_DESC; bcopy((char *)pTuple->mBlkHdr.mData, (char*)pTxDescCurr->buf_ptr, pTxDescCurr->bytecnt); } else pTxDescCurr->buf_ptr = (UINT32)pTuple->mBlkHdr.mData; pTxDescCurr->shadowOwner = SHADOW_OWNER_BY_CPU; pTxDescCurr->pointerToRxQueue = (unsigned)NULL; /* Release information */ pTxDescLast = pTxDescCurr; /* Make the Tx cluster coherent with memory */ cacheFlush(DATA_CACHE, (void*)pTxDescCurr->buf_ptr, (size_t)pTxDescCurr->bytecnt); pTxDescCurr = (TX_DESC*)(pTxDescCurr->next_desc_ptr); /* Move to the next mBlk within the packet */ pTuple = pTuple->mBlkHdr.mNext; } pTxDescLast->cmd_sts |= (LAST | ENABLE_INTERRUPT); pTxDescLast->pointerToRxQueue = (UINT32)pMblk; /* Release information */ pMblk = pMblk->mBlkHdr.mNextPkt; /* ** Moved to last thing done, to insure DMA engine sees the ** end of buffer actions */ pTxDescFirst->cmd_sts |= OWNER_BY_GT; } /* update the current descriptor */ pDrvCtrl->currTxDescPtr = pTxDescCurr; /* Flush the write pipe */ CACHE_PIPE_FLUSH (); /* Give send command */ PORT_REG_WRITE(SDMA_COMMAND_REG, PORT_SDMA_START_TX_LOW); /* interlock with wancomCFDFree */ END_TX_SEM_GIVE ( &pDrvCtrl->endObj); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1); WANCOM_DRV_LOG (DRV_DEBUG_TX, ("wancomSend...Done\n"), 1, 2, 3, 4, 5, 6); return(OK); }/******************************************************************************** wancomInt - entry point for handling interrupts from the Galileo device.** The interrupting events are acknowledged to the device, so that the device* will de-assert its interrupt signal. The amount of work done here is kept* to a minimum; the bulk of the work is deferred to the netTask.** RETURNS: N/A*/LOCAL void wancomInt ( WANCOM_DRV_CTRL * pDrvCtrl /* pointer to WANCOM_DRV_CTRL structure */ ) { UINT32 causeRegVal; UINT32 maskRegVal; int spuriousInt = 1 ; /* clear chip level interrupt pending, use byte access */ PORT_REG_READ (INTERRUPT_CAUSE_REG, &causeRegVal); PORT_REG_READ (INTERRUPT_MASK_REG, &maskRegVal); /* handle transmit interrupts */ if ( causeRegVal & maskRegVal & TX_END_LOW_PRIO ) { GT64260_INT_ACK (TX_END_LOW_PRIO); if ( pDrvCtrl->txHandle == FALSE ) { GT64260_INT_DISABLE; pDrvCtrl->txHandle = TRUE; (void) netJobAdd ((FUNCPTR) wancomCFDFree, (int) pDrvCtrl, 0, 0, 0, 0); } spuriousInt = 0 ; } /* handle receive interrupts */ if ( causeRegVal & maskRegVal & RX_BUFFER_RETURN ) { GT64260_INT_ACK (RX_BUFFER_RETURN); if ( pDrvCtrl->rxHandle == FALSE ) { GT64260_INT_DISABLE; pDrvCtrl->rxHandle = TRUE; (void) netJobAdd ((FUNCPTR) wancomHandleRecvInt, (int) pDrvCtrl, 0, 0, 0, 0); } spuriousInt = 0 ; } if ( spuriousInt ) GT64260_INT_ENABLE; }/******************************************************************************** wancomHandleRecvInt - service task-level interrupts for receive frames** This routine is run in netTask's context. The ISR scheduled* this routine so that it could handle receive packets at task level.** RETURNS: N/A*/LOCAL void wancomHandleRecvInt ( WANCOM_DRV_CTRL * pDrvCtrl /* pointer to WANCOM_DRV_CTRL structure */ ) { RX_DESC *pRxDesc; RX_DESC *pRxDescLayerUp; WANCOM_DRV_LOG (DRV_DEBUG_RX, ("wancomHandleRecvInt: \n"), 0, 0, 0, 0, 0, 0); /* get the first used RFD */ WANCOM_RFD_GET (pRxDesc); WANCOM_DRV_LOG (DRV_DEBUG_RX, ("Process Rx desc 0x%x buf 0x%x\n"), (UINT32)pRxDesc, (UINT32)pRxDesc->buf_ptr, 0, 0, 0, 0); /* while RFDs to be processed */ FOREVER { /* check for RFDs availability */ if ( pRxDesc == NULL ) /* General fault */ { pDrvCtrl->rxHandle = FALSE; WANCOM_DRV_LOG (DRV_DEBUG_RX_ERR, ("Rx queue head is NULL!\n"), 0, 0, 0, 0, 0, 0); return; } if ( pRxDesc->next_desc_ptr == (UINT32)pDrvCtrl->dummyRxDescPtr ) { WANCOM_DRV_LOG (DRV_DEBUG_RX_ERR, ("End of chain !!\n"), 0, 0, 0, 0, 0, 0); break; } if ( pRxDesc->cmd_sts & OWNER_BY_GT ) { break; } /* Prepare the Rx desc pointer to move to the upper layer */ pRxDescLayerUp = pRxDesc; /* Point pRxDesc to the next Rx descriptor in the queue */ pRxDesc = (RX_DESC*)pRxDesc->next_desc_ptr; pRxDescLayerUp->next_desc_ptr = (unsigned)NULL; wancomReceive (pDrvCtrl, (RX_DESC*)pRxDescLayerUp); } /* Update new head for Rx queue */ WANCOM_RFD_SET(pRxDesc); /* No more Rx packet to process. Interlock with wancomInt */ pDrvCtrl->rxHandle = FALSE; /* Flush the write pipe */ CACHE_PIPE_FLUSH (); /* re-enable receiver interrupts */ GT64260_INT_ENABLE; WANCOM_DRV_LOG (DRV_DEBUG_RX, ("wancomHandleRecvInt... Done, \n"), 0, 0, 0, 0, 0, 0); }/******************************************************************************** wancomReceive - pass a received frame to the next layer up** RETURNS: N/A*/LOCAL void wancomReceive ( WANCOM_DRV_CTRL * pDrvCtrl, /* pointer to WANCOM_DRV_CTRL structure */ RX_DESC * pRxDesc /* pointer to a RFD */ ) { M_BLK_ID pMblk = NULL; CL_BLK_ID pClBlk = NULL; /* pass the packet up only if reception was Ok */ if ( pRxDesc->cmd_sts & ERROR_SUMMARY ) { WANCOM_DRV_LOG (DRV_DEBUG_RX_ERR, ("Error in Rx desc 0x%x\n"), pRxDesc, 0, 0, 0, 0, 0); goto wancomRecvError; } if ( (pMblk = netMblkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA)) == NULL ) { WANCOM_DRV_LOG (DRV_DEBUG_RX_ERR, ("netMblkGet failed !!!\n"),0,0,0,0,0,0); goto wancomRecvError; } if ( (pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) == NULL ) { WANCOM_DRV_LOG (DRV_DEBUG_RX_ERR, ("netClBlkGet failed !!!\n"),0,0,0,0,0,0); goto wancomRecvError; } if ( netClBlkJoin (pClBlk, (char*)pRxDesc->buf_ptr, RX_BUFFER_DEFAULT_SIZE, NULL, 0, 0, 0) == NULL ) { WANCOM_DRV_LOG (DRV_DEBUG_RX_ERR, ("netClBlkJoin failed !!!\n"),0,0,0,0,0,0); goto wancomRecvError; } if ( netMblkClJoin (pMblk, pClBlk) == NULL ) { WANCOM_DRV_LOG (DRV_DEBUG_RX_ERR, ("netMblkClJoin failed !!!\n"),0,0,0,0,0,0); goto wancomRecvError; } END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1); pMblk->mBlkHdr.mFlags |= M_PKTHDR; pMblk->mBlkHdr.mData = (char *) (pRxDesc->buf_ptr); pMblk->mBlkHdr.mLen = pRxDesc->bytecnt; pMblk->mBlkPktHdr.len = pMblk->mBlkHdr.mLen; /* put the used RFD back on the RFD queue */ wancomRFDReturn(pDrvCtrl, pRxDesc, 1); /* Make the Rx cluster coherent with memory */ cacheInvalidate(DATA_CACHE, pMblk->mBlkHdr.mData ,pMblk->mBlkHdr.mLen); /* Send the packet up the stack */ END_RCV_RTN_CALL (&pDrvCtrl->endObj, pMblk); WANCOM_DRV_LOG (DRV_DEBUG_RX, ("wancomReceive... Done, \n"), 0, 0, 0, 0, 0, 0); return; wancomRecvError: if ( pMblk != NULL ) netMblkFree (pDrvCtrl->endObj.pNetPool, pMblk); if ( pClBlk != NULL ) netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk); if ( pRxDesc->buf_ptr != (unsigned)NULL ) netClFree (pDrvCtrl->endObj.pNetPool, (UCHAR *) pRxDesc->buf_ptr); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); /* put the errored RFD on the RFD queue */ wancomRFDReturn(pDrvCtrl, pRxDesc, 1); }/**************************************************************************** wancomRFDReturn - put a Receive Frame on the Receive Queue** This routine puts a Receive Frame on the Receive Queue.** RETURNS: N/A**/LOCAL void wancomRFDReturn ( WANCOM_DRV_CTRL * pDrvCtrl, /* pointer to WANCOM_DRV_CTRL structure */ RX_DESC * pRxDesc, /* pointer to a RFD */ int allocNewBuffer ) { RX_DESC * pRxDescOldTail; /* pointer to a RFD */ UINT32 pNewRFD = (UINT32)NULL; if ( WANCOM_FLAG_ISSET(WANCOM_POLLING) == 0 ) END_RX_SEM_TAKE(pDrvCtrl->rxSemId, WAIT_FOREVER); WANCOM_DRV_LOG ((DRV_DEBUG_POLL_RX|DRV_DEBUG_RX), ("Releasing Rx desc 0x%x...\n"), (UINT32)pRxDesc, 0, 0, 0, 0, 0); /* Assign the returned Rx descriptor with new cluster */ if ( allocNewBuffer == 1 ) { if ( (pNewRFD = (UINT32) netClusterGet (pDrvCtrl->endObj.pNetPool, pDrvCtrl->pClPoolId)) == (UINT32)NULL ) goto wancomRFDReturnError; pRxDesc->buf_ptr = pNewRFD; } /* Insert the Rx desc between tail and dummy */ pRxDesc->next_desc_ptr = (UINT32)pDrvCtrl->dummyRxDescPtr; pDrvCtrl->tailRxDescPtr->next_desc_ptr = (UINT32)pRxDesc; /* save the old tail pointer */ pRxDescOldTail = (RX_DESC*)pDrvCtrl->tailRxDescPtr; /* Update drvCtrl structure with the new tail */ pDrvCtrl->tailRxDescPtr = pRxDesc; /* Return the old tail to GT ownership */ pRxDescOldTail->cmd_sts |= OWNER_BY_GT; if ( WANCOM_FLAG_ISSET(WANCOM_POLLING) == 0 ) END_RX_SEM_GIVE(pDrvCtrl->rxSemId); return; wancomRFDReturnError: if ( WANCOM_FLAG_ISSET(WANCOM_POLLING) == 0 ) END_RX_SEM_GIVE(pDrvCtrl->rxSemId); WANCOM_DRV_LOG((DRV_DEBUG_POLL_RX|DRV_DEBUG_RX),("Could not retrieve Rx cluster !! \n"),0,0,0,0,0,0); END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1); }/**************************************************************************** wancomEndDbg - Print pDrvCtrl information regarding Tx ring and Rx queue desc.** RETURNS: N/A**/void wancomEndDbg ( WANCOM_DRV_CTRL * pDrvCtrl /* pointer to WANCOM_DRV_CTRL structure */ ) { printf("pDrvCtrl->headRxDescPtr = 0x%x\n",(UINT32)pDrvCtrl->headRxDescPtr); printf("pDrvCtrl->tailRxDescPtr = 0x%x\n",(UINT32)pDrvCtrl->tailRxDescPtr); printf("pDrvCtrl->dummyRxDescPtr = 0x%x\n",(UINT32)pDrvCtrl->dummyRxDescPtr); printf("pDrvCtrl->usedTxDescPtr = 0x%x\n",(UINT32)pDrvCtrl->usedTxDescPtr); printf("pDrvCtrl->currTxDescPtr = 0x%x\n",(UINT32)pDrvCtrl->currTxDescPtr); }/**************************************************************************** wancomCFDFree - free all used command frames
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -