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

📄 xtemac_fifo.c

📁 xilinx trimode mac driver for linux
💻 C
📖 第 1 页 / 共 3 页
字号:
        return(XST_DEVICE_IS_STOPPED);    }    /* If the receive length FIFO is empty, then there's no packet waiting */    RegIPISR = XTemac_mGetIpifReg(XTE_IPISR_OFFSET);    if (!(RegIPISR & XTE_IPXR_RECV_DONE_MASK))    {        return(XST_NO_DATA);    }    /* Get the length */    *ByteCountPtr = XTemac_mGetIpifReg(XTE_RPLR_OFFSET);    /* The IPXR_RECV_DONE_MASK status bit is tied to the RSR register. To clear     * this condition, read from the RSR (which has no information) then write     * to the IPISR register to ack the status.     */    RegRSR = XTemac_mGetIpifReg(XTE_RSR_OFFSET);    XTemac_mSetIpifReg(XTE_IPISR_OFFSET, XTE_IPXR_RECV_DONE_MASK);    /* Return sucess */    return(XST_SUCCESS);}/******************************************************************************//** * Copy data from the receive packet FIFO into a user buffer. The number of * bytes to copy is derived from XTemac_FifoRecv(). The packet data may be * copied out of the FIFO all at once or with multiple calls to this function. * The latter method supports systems that keep packet data in non-contiguous * memory regions. For example: * <pre> *    if (XTemac_FifoRecv(Tptr, &PacketLength) == XST_SUCCESS) *    { *       if (PacketLength > 14) *       { *          HeaderLength = 14; *          PayloadLength = PacketLength - HeaderLength; * *          Status =  XTemac_FifoRead(Tptr, UserHeaderBuf, HeaderLength, *                                    XTE_PARTIAL_PACKET); *          Status |= XTemac_FifoRead(Tptr, UserPayloadBuf, PayloadLength, *                                    XTE_END_OF_PACKET); * *          if (Status != XST_SUCCESS) *          { *             // handle error *          } *       } *    } * </pre> * * If the user's buffer is not aligned on a 4 byte boundary, then the transfer * may take longer to complete. * * @param InstancePtr is a pointer to the instance to be worked on. * @param BufPtr is the user buffer that will recieve packet data from the FIFO. *        The buffer may be on any alignment. * @param ByteCount is the number of bytes to transfer * @param Eop specifies whether the last byte read is the last byte of a packet. *        If set to XTE_END_OF_PACKET, then any partial bytes being buffered by *        the driver at the end of the transfer are discarded. These discarded *        bytes are filler provided by the hardware and have no meaning. If set *        to XTE_PARTIAL_PACKET, then more packet data is expected to be read *        through more calls to this function. Failure to use this parameter *        properly will result in undefined filler bytes being copied into *        BufPtr. * * @return * - XST_SUCCESS if the data was transferred to the user buffer * - XST_DEVICE_IS_STOPPED if the device has not been started. * - XST_NO_DATA if there was not enough data in the packet FIFO to satisfy the *   request. * * @note * Do not attempt to read more than one packets worth of data at a time with * this function. ******************************************************************************/XStatus XTemac_FifoRead(XTemac *InstancePtr, void *BufPtr, u32 ByteCount,                        int Eop){    XStatus Status;    XASSERT_NONVOID(InstancePtr != NULL);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    XASSERT_NONVOID(!((Eop != XTE_END_OF_PACKET) && (Eop != XTE_PARTIAL_PACKET)));    /* Make sure device is ready for this operation */    if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED)    {        return(XST_DEVICE_IS_STOPPED);    }    /* Transfer the data using the best/fastest method */    Status = InstancePtr->RecvFifo.XferFn(&InstancePtr->RecvFifo, BufPtr,                                          ByteCount, Eop);    /* Return correct status */    if (Status == XST_NO_DATA)    {        return(XST_NO_DATA);    }    else    {        return(XST_SUCCESS);    }}/******************************************************************************//** * Retrieve the number of free bytes in the packet FIFOs. * * For the transmit packet FIFO, the number returned is the number of bytes * that can be written by XTemac_FifoWrite(). If a non-zero number is returned, * then at least 1 packet of that size can be transmitted. * * For the receive packet FIFO, the number returned is the number of bytes that * can arrive from an external Ethernet device. This number does not reflect * the state of the receive length FIFO. If this FIFO is full, then arriving * packets will get dropped by the HW if there is no place to store the length. * * @param InstancePtr is a pointer to the instance to be worked on. * @param Direction selects which packet FIFO to examine. If XTE_SEND, then *        the transmit packet FIFO is selected. If XTE_RECV, then the receive *        packet FIFO is selected. * * @return * Number of bytes available in the selected packet FIFO. * ******************************************************************************/u32 XTemac_FifoGetFreeBytes(XTemac *InstancePtr, u32 Direction){    u32 RegIPISR;    u32 Count;    XASSERT_NONVOID(InstancePtr != NULL);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    XASSERT_NONVOID(!(Direction & ~(XTE_SEND | XTE_RECV)));    /* For the send direction, even though there may be room in the     * packet FIFO, the length FIFO may be full. When this is the case,     * another packet cannot be transmiited so return 0.     */    if (Direction == XTE_SEND)    {        /* Check length FIFO */        RegIPISR = XTemac_mGetIpifReg(XTE_IPISR_OFFSET);        if (RegIPISR & XTE_IPXR_XMIT_LFIFO_FULL_MASK)        {            return(0);        }        /* Get FIFO entries */        Count = XPF_V200A_GET_COUNT(&InstancePtr->SendFifo.Fifo);    }    /* Handle receive direction */    else    {        Count = XPF_V200A_COUNT_MASK -            XPF_V200A_GET_COUNT(&InstancePtr->RecvFifo.Fifo);    }    /* Multiply free entries by the width of the packet FIFO to arrive at     * bytes     */    return(Count * InstancePtr->RecvFifo.Width);}/******************************************************************************//** * Query the device for the latest transmit status for FIFO direct frame * transfer mode. This function should be used for polled mode operation only. * * @param InstancePtr is a pointer to the instance to be worked on. * @param SendStatusPtr is the contents of the XTE_TSR_OFFSET register when the *        return code is XST_FAILURE. Otherwise 0 is returned. * * @return * - XST_NO_DATA if a transmit status is not currently available. * - XST_DEVICE_IS_STOPPED if the device has not been started. * - XST_NOT_POLLED if the device has not been set to polled mode. * - XST_SUCCESS if a transmit status was found and indicates that there was *   no error. * - XST_FIFO_ERROR if the transmit length or transmit status FIFOs error has *   been detected. If this error is returned, then the device must be reset *   before this function will return a valid transmit status indication. * - XST_PFIFO_ERROR if the transmit packet FIFO is deadlocked. If this error *   is returned, then the device must be reset before this function will *   return a valid transmit status indication * - XST_IPIF_ERROR if there has been a data phase timeout or transaction error *   in the IPIF. This is a fatal error. * * @note * When XST_FAILURE is returned with the XTE_TSR_PFIFOU_MASK bit set in the * SendStatusPtr parameter, then an attempt was made to transmit more data than * was present in the packet FIFO. No reset is required in this situation. * ******************************************************************************/XStatus XTemac_FifoQuerySendStatus(XTemac *InstancePtr, u32 *SendStatusPtr){    u32 RegDISR;    u32 RegIPISR;    XASSERT_NONVOID(InstancePtr != NULL);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    XASSERT_NONVOID(SendStatusPtr != NULL);    /* Make sure device is ready for this operation */    if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED)    {        return(XST_DEVICE_IS_STOPPED);    }    /* Have to be in polled mode to use this function */    if (!(InstancePtr->Options & XTE_POLLED_OPTION))    {        return(XST_NOT_POLLED);    }    /* Make sure send packet FIFO isn't deadlocked */    RegDISR = XTemac_mGetIpifReg(XTE_DISR_OFFSET);    if (RegDISR & XTE_DXR_SEND_FIFO_MASK)    {        XTemac_mBumpStats(TxPktFifoErrors, 1);        return(XST_PFIFO_ERROR);    }    /* Make sure no IPIF errors are present */    if (RegDISR & (XTE_DXR_TERR_MASK | XTE_DXR_DPTO_MASK))    {        XTemac_mBumpStats(IpifErrors, 1);        return(XST_IPIF_ERROR);    }    /* Read the IPISR     * If any errors are detetected, try to clear and return error     */    RegIPISR = XTemac_mGetIpifReg(XTE_IPISR_OFFSET);    if (RegIPISR & XTE_IPXR_XMIT_ERROR_MASK)    {        XTemac_mSetIpifReg(XTE_IPISR_OFFSET, RegIPISR & XTE_IPXR_XMIT_ERROR_MASK);        XTemac_mBumpStats(FifoErrors, 1);        return(XST_FIFO_ERROR);    }    /* No FIFO errors, so see of a transmit has completed */    if (!(RegIPISR & XTE_IPXR_XMIT_DONE_MASK))    {        return(XST_NO_DATA);    }    /* Transmit has completed, get the status, ack the condition */    *SendStatusPtr = XTemac_mGetIpifReg(XTE_TSR_OFFSET);    XTemac_mSetIpifReg(XTE_IPISR_OFFSET, XTE_IPXR_XMIT_DONE_MASK);    /* no errors to report */    return(XST_SUCCESS);}/******************************************************************************//** * Query the device for the latest receive status for FIFO direct frame * transfer mode. This function should be used for polled mode operation only. * * @param InstancePtr is a pointer to the instance to be worked on. * * @return * - XST_SUCCESS if a frame has been received and no receive error was detected. * - XST_DEVICE_IS_STOPPED if the device has not been started. * - XST_NO_DATA if no frame has been received and no receive related error has *   been detected. * - XST_NOT_POLLED if the device has not been set to polled mode. * - XST_DATA_LOST if the device reports that it dropped a receive frame. This *   is not a serious problem but may indicate that frames are arriving faster *   than the system can process them. * - XST_FIFO_ERROR if an error was detected with the receive length FIFO. If *   this error is returned, then the device must be reset before any new frame *   can be received. * - XST_PFIFO_ERROR if the receive packet FIFO is deadlocked. If this error is *   returned, then the device must be reset before any new frame can be *   received. * - XST_IPIF_ERROR if there has been a data phase timeout or transaction error *   in the IPIF. This is a fatal error. * * @note * In situations where simultaneously a frame has been received for which an * XST_SUCCESS can be returned and a dropped frame for which an XST_DATA_LOST * can be returned, then this function will give priority to XST_SUCCESS so the * user can receive the frame. ******************************************************************************/XStatus XTemac_FifoQueryRecvStatus(XTemac *InstancePtr){    u32 RegDISR;    u32 RegIPISR;    XASSERT_NONVOID(InstancePtr != NULL);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    /* Make sure device is ready for this operation */    if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED)    {        return(XST_DEVICE_IS_STOPPED);    }    /* Have to be in polled mode to use this function */    if (!(InstancePtr->Options & XTE_POLLED_OPTION))    {        return(XST_NOT_POLLED);    }    /* Read the DISR */    RegDISR = XTemac_mGetIpifReg(XTE_DISR_OFFSET);    /* Make sure recv packet FIFO isn't deadlocked */    if (RegDISR & XTE_DXR_RECV_FIFO_MASK)    {        XTemac_mBumpStats(RxPktFifoErrors, 1);        return(XST_PFIFO_ERROR);    }    /* Make sure no IPIF errors are present */    if (RegDISR & (XTE_DXR_TERR_MASK | XTE_DXR_DPTO_MASK))    {        XTemac_mBumpStats(IpifErrors, 1);        return(XST_IPIF_ERROR);    }    /* Read the IPISR */    RegIPISR = XTemac_mGetIpifReg(XTE_IPISR_OFFSET);    /* Check for other recv related FIFO errors */    if (RegIPISR & (XTE_IPXR_RECV_ERROR_MASK - XTE_IPXR_RECV_DROPPED_MASK))    {        XTemac_mSetIpifReg(XTE_IPISR_OFFSET, RegIPISR & XTE_IPXR_RECV_ERROR_MASK);        XTemac_mBumpStats(FifoErrors, 1);        return(XST_FIFO_ERROR);    }    /* See if a frame has been received */    if (RegIPISR & XTE_IPXR_RECV_DONE_MASK)    {        return(XST_SUCCESS);    }    /* If option to detect recv reject errors is set, check for rejected     * receive frames. If one is detected, clear it and return error.     */    if (InstancePtr->Options & XTE_REPORT_RXERR_OPTION)    {        if (RegIPISR & XTE_IPXR_RECV_DROPPED_MASK)        {            XTemac_mSetIpifReg(XTE_IPISR_OFFSET,                               RegIPISR & XTE_IPXR_RECV_DROPPED_MASK);            return(XST_DATA_LOST);        }    }    /* No frame has been received and no errors detected */    return(XST_NO_DATA);}/******************************************************************************** Algorithm to write to a 64 bit wide transmit packet FIFO through the holding* buffer.** @param FPtr is a pointer to a Temac FIFO instance to worked on.* @param BufPtr is the source buffer address on any alignment* @param ByteCount is the number of bytes to transfer* @param Eop specifies whether the last byte written is the last byte of the*        packet.** @return XST_SUCCESS*******************************************************************************/static XStatus Write_64(XTemac_PacketFifo *Fptr, void *BufPtr,                        u32 ByteCount, int Eop){    unsigned BufAlignment = (unsigned)BufPtr & 3;    unsigned PartialBytes;    unsigned HoldAlignment = mHold_GetIndex(Fptr);    /* Case 1: Buffer aligned on 4-byte boundary and Hold is empty     *     *   1. Write all bytes using the fastest transfer method     */    if ((BufAlignment == 0) && (mHoldS_IsEmpty(Fptr)))    {        Write64_Aligned(Fptr, (u32*)BufPtr, ByteCount);    }    /* Case 2: Buffer and Hold are byte aligned with each other     *     *   1. Transfer enough bytes from the buffer to the Hold to trigger a flush     *      to the FIFO.     *     *   2. The state of the buffer and Hold are as described by Case 1 so     *      write remaining bytes using the fastest transfer method     */    else if (BufAlignment == (HoldAlignment % PFIFO_64BIT_WIDTH_BYTES))    {        PartialBytes = PFIFO_64BIT_WIDTH_BYTES - HoldAlignment;        if (ByteCount < PartialBytes)        {            PartialBytes = ByteCount;        }

⌨️ 快捷键说明

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