使用virtex4,xps_ll_temac, 进行网络处理遇到一个问题: 使用uboot,下面的函数在没有使用数据cache时,报文接收正确, 但是当使用数据cache时,接收异常,打印出调试信息 Received a frame of 67174464 bytes Received a frame of 67174464 bytes Received a frame of 67174464 bytes 明显是接收的长度有问题, edk给的sgdma的例子都是使用中断dma方式,在中断中判断 接收状态, 是否使能数据cache后,必须判断中断状态,sgdma的状态才是准确的? int eth_rx(void) { u32 RecvFrameLength; int Status; XLlDma_Bd *RxBdPtr; u32 BdCount; XLlDma_BdRing *RxRingPtr = &XLlDma_mGetRxRing(&LlDma); BdCount = XLlDma_BdRingFromHw(RxRingPtr, XLLDMA_ALL_BDS, &RxBdPtr); /* If there are any buffer descriptors ready to be received from the * DMA then send the buffer up the network stack */ if (BdCount > 0) { RecvFrameLength = XLlDma_mBdRead(RxBdPtr, XLLDMA_BD_USR4_OFFSET); debug_printf("Received a frame of %d bytes\r\n", RecvFrameLength); NetReceive((uchar *)RxFrame, RecvFrameLength); /* * Return the RxBD back to the channel for later allocation. Free the * exact number we just post processed. */ Status = XLlDma_BdRingFree(RxRingPtr, 1, RxBdPtr); if (Status != XST_SUCCESS) { debug_printf("Error freeing up RxBD\n\r"); return 0; } /* * Allocate 1 RxBD. Note that TEMAC utilizes an in-place allocation * scheme. The returned Bd1Ptr will point to a free BD in the memory * segment setup with the call to XLlTemac_SgSetSpace() */ Status = XLlDma_BdRingAlloc(RxRingPtr, 1, &RxBdPtr); if (Status != XST_SUCCESS) { debug_printf("Error allocating RxBD"); return 0; }
/* * Setup the BD. The BD template used in the call to XLlTemac_SgSetSpace() * set the "last" field of all RxBDs. Therefore we are not required to * issue a XLlDma_Bd_mSetLast(Bd1Ptr) here. */ XLlDma_mBdSetBufAddr(RxBdPtr, &RxFrame); XLlDma_mBdSetLength(RxBdPtr, sizeof(RxFrame)); XLlDma_mBdSetStsCtrl(RxBdPtr, XLLDMA_BD_STSCTRL_SOP_MASK | XLLDMA_BD_STSCTRL_EOP_MASK); /* * Enqueue to HW again so it can receive another frame */ Status = XLlDma_BdRingToHw(RxRingPtr, 1, RxBdPtr); if (Status != XST_SUCCESS) { debug_printf("Error committing RxBD to HW\n\r"); return 0; } return 1; } else { return 0; } }
|