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

📄 xemac_polled.c

📁 powerpc405开发板的linux网口驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    /*     * Underrun errors     */    if (IntrStatus & (XEM_EIR_XMIT_SFIFO_UNDER_MASK |        XEM_EIR_XMIT_LFIFO_UNDER_MASK))    {        InstancePtr->Stats.XmitUnderrunErrors++;        InstancePtr->Stats.FifoErrors++;        return XST_FIFO_ERROR;    }    /*     * Clear the interrupt status register of transmit statuses     */    XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,                           IntrStatus & XEM_EIR_XMIT_ALL_MASK);    /*     * Collision errors are stored in the transmit status register     * instead of the interrupt status register     */    if (XmitStatus & XEM_TSR_EXCESS_DEFERRAL_MASK)    {        InstancePtr->Stats.XmitExcessDeferral++;        return XST_EMAC_COLLISION_ERROR;    }    if (XmitStatus & XEM_TSR_LATE_COLLISION_MASK)    {        InstancePtr->Stats.XmitLateCollisionErrors++;        return XST_EMAC_COLLISION_ERROR;    }    return XST_SUCCESS;}/*****************************************************************************//**** Receive an Ethernet frame in polled mode. The device/driver must be in polled* mode before calling this function. The driver receives the frame directly* from the MAC's packet FIFO. This is a non-blocking receive, in that if there* is no frame ready to be received at the device, the function returns with an* error. The MAC's error status is not checked, so statistics are not updated* for polled receive. The buffer into which the frame will be received must be* 32-bit aligned.** @param InstancePtr is a pointer to the XEmac instance to be worked on.* @param BufPtr is a pointer to a aligned buffer into which the received*        Ethernet frame will be copied.* @param ByteCountPtr is both an input and an output parameter. It is a pointer*        to a 32-bit word that contains the size of the buffer on entry into the*        function and the size the received frame on return from the function.** @return** - XST_SUCCESS if the frame was sent successfully* - XST_DEVICE_IS_STOPPED if the device has not yet been started* - XST_NOT_POLLED if the device is not in polled mode* - XST_NO_DATA if there is no frame to be received from the FIFO* - XST_BUFFER_TOO_SMALL if the buffer to receive the frame is too small for*   the frame waiting in the FIFO.* - XST_FIFO_ERROR if the FIFO was overrun or underrun. This error is critical*   and requires the caller to reset the device.** @note** Input buffer must be big enough to hold the largest Ethernet frame. ** @internal** The EMAC uses FIFOs behind its length and status registers. For this reason,* it is important to keep the length, status, and data FIFOs in sync when* reading or writing to them.*******************************************************************************/XStatus XEmac_PollRecv(XEmac *InstancePtr, Xuint8 *BufPtr,                       Xuint32 *ByteCountPtr){    XStatus Result;    Xuint32 PktLength;    Xuint32 IntrStatus;    XASSERT_NONVOID(InstancePtr != XNULL);    XASSERT_NONVOID(BufPtr != XNULL);    XASSERT_NONVOID(ByteCountPtr != XNULL);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    /*     * Be sure the device is configured for polled mode and it is started     */    if (!InstancePtr->IsPolled)    {        return XST_NOT_POLLED;    }    if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED)    {        return XST_DEVICE_IS_STOPPED;    }    /*     * Make sure the buffer is big enough to hold the maximum frame size.     * We need to do this because as soon as we read the MAC's packet length     * register, which is actually a FIFO, we remove that length from the     * FIFO.  We do not want to read the length FIFO without also reading the     * data FIFO since this would get the FIFOs out of sync.  So we have to     * make this restriction.     */    if (*ByteCountPtr < XEM_MAX_FRAME_SIZE)    {        return XST_BUFFER_TOO_SMALL;    }    /*     * First check for packet FIFO deadlock and return an error if it has     * occurred. A reset by the caller is necessary to correct this problem.     */    if (XPF_V200A_IS_DEADLOCKED(&InstancePtr->RecvFifo))    {        InstancePtr->Stats.FifoErrors++;        return XST_FIFO_ERROR;    }    /*     * Get the interrupt status to know what happened (whether an error occurred     * and/or whether frames have been received successfully). When clearing the     * intr status register, clear only statuses that pertain to receive.     */    IntrStatus = XIIF_V123B_READ_IISR(InstancePtr->BaseAddress);    XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress,                           IntrStatus & XEM_EIR_RECV_ALL_MASK);    /*     * Check receive errors and bump statistics so the caller will have a clue     * as to why data may not have been received. We continue on if an error     * occurred since there still may be frames that were received successfully.     */    if (IntrStatus & (XEM_EIR_RECV_LFIFO_OVER_MASK |        XEM_EIR_RECV_DFIFO_OVER_MASK))    {        InstancePtr->Stats.RecvOverrunErrors++;        InstancePtr->Stats.FifoErrors++;    }    if (IntrStatus & XEM_EIR_RECV_LFIFO_UNDER_MASK)    {        InstancePtr->Stats.RecvUnderrunErrors++;        InstancePtr->Stats.FifoErrors++;    }    /*     * General receive errors     */    if (IntrStatus & XEM_EIR_RECV_ERROR_MASK)    {        if (IntrStatus & XEM_EIR_RECV_MISSED_FRAME_MASK)        {            InstancePtr->Stats.RecvMissedFrameErrors =                    XIo_In32(InstancePtr->BaseAddress + XEM_RMFC_OFFSET);        }        if (IntrStatus & XEM_EIR_RECV_COLLISION_MASK)        {            InstancePtr->Stats.RecvCollisionErrors =                    XIo_In32(InstancePtr->BaseAddress + XEM_RCC_OFFSET);        }        if (IntrStatus & XEM_EIR_RECV_FCS_ERROR_MASK)        {            InstancePtr->Stats.RecvFcsErrors =                    XIo_In32(InstancePtr->BaseAddress + XEM_RFCSEC_OFFSET);        }        if (IntrStatus & XEM_EIR_RECV_LEN_ERROR_MASK)        {            InstancePtr->Stats.RecvLengthFieldErrors++;        }        if (IntrStatus & XEM_EIR_RECV_SHORT_ERROR_MASK)        {            InstancePtr->Stats.RecvShortErrors++;        }        if (IntrStatus & XEM_EIR_RECV_LONG_ERROR_MASK)        {            InstancePtr->Stats.RecvLongErrors++;        }        if (IntrStatus & XEM_EIR_RECV_ALIGN_ERROR_MASK)        {            InstancePtr->Stats.RecvAlignmentErrors =                    XIo_In32(InstancePtr->BaseAddress + XEM_RAEC_OFFSET);        }    }    /*     * Before reading from the length FIFO, make sure the length FIFO is not     * empty. We could cause an underrun error if we try to read from an     * empty FIFO.     */    if ((IntrStatus & XEM_EIR_RECV_DONE_MASK) == 0)    {        return XST_NO_DATA;    }    /*     * Determine, from the MAC, the length of the next packet available     * in the data FIFO (there should be a non-zero length here)     */    PktLength = XIo_In32(InstancePtr->BaseAddress + XEM_RPLR_OFFSET);    if (PktLength == 0)    {        return XST_NO_DATA;    }    /*     * Write the RECV_DONE bit in the status register to clear it. This bit     * indicates the RPLR is non-empty, and we know it's set at this point.     * We clear it so that subsequent entry into this routine will reflect the     * current status. This is done because the non-empty bit is latched in the     * IPIF, which means it may indicate a non-empty condition even though     * there is something in the FIFO.     */    XIIF_V123B_WRITE_IISR(InstancePtr->BaseAddress, XEM_EIR_RECV_DONE_MASK);    /*     * We assume that the MAC never has a length bigger than the largest     * Ethernet frame, so no need to make another check here.     */    /*     * This is a non-blocking read. The FIFO returns an error if there is     * not at least the requested amount of data in the FIFO.     */    Result = XPacketFifoV200a_Read(&InstancePtr->RecvFifo, BufPtr, PktLength);    if (Result != XST_SUCCESS)    {        return Result;    }    InstancePtr->Stats.RecvFrames++;    InstancePtr->Stats.RecvBytes += PktLength;    *ByteCountPtr = PktLength;    return XST_SUCCESS;}

⌨️ 快捷键说明

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