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

📄 xemac_selftest.c

📁 powerpc405开发板的linux网口驱动程序
💻 C
字号:
/* $Id: xemac_selftest.c,v 1.1 2005/10/26 15:44:52 meinelte Exp $ *//********************************************************************************       XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"*       AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND*       SOLUTIONS FOR XILINX DEVICES.  BY PROVIDING THIS DESIGN, CODE,*       OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,*       APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION*       THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,*       AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE*       FOR YOUR IMPLEMENTATION.  XILINX EXPRESSLY DISCLAIMS ANY*       WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE*       IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR*       REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF*       INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS*       FOR A PARTICULAR PURPOSE.**       (c) Copyright 2003 Xilinx Inc.*       All rights reserved.*******************************************************************************//*****************************************************************************//**** @file xemac_selftest.c** Self-test and diagnostic functions of the XEmac driver.** <pre>* MODIFICATION HISTORY:** Ver   Who  Date     Changes* ----- ---- -------- -----------------------------------------------* 1.00a rpm  07/31/01 First release* 1.00b rpm  02/20/02 Repartitioned files and functions* 1.00c rpm  12/05/02 New version includes support for simple DMA* 1.00d rpm  09/26/03 New version includes support PLB Ethernet and v2.00a of*                     the packet fifo driver.* </pre>*******************************************************************************//***************************** Include Files *********************************/#include "xbasic_types.h"#include "xemac_i.h"#include "xio.h"#include "xipif_v1_23_b.h"      /* Uses v1.23b of the IPIF *//************************** Constant Definitions *****************************//* * Set some reset state defines for use in the self-test */#define XEM_ECR_RESET_STATE         (XEM_ECR_XMIT_RESET_MASK |       \                                     XEM_ECR_RECV_RESET_MASK |       \                                     XEM_ECR_PHY_ENABLE_MASK |       \                                     XEM_ECR_XMIT_PAD_ENABLE_MASK |  \                                     XEM_ECR_XMIT_FCS_ENABLE_MASK |  \                                     XEM_ECR_XMIT_ADDR_INSERT_MASK | \                                     XEM_ECR_XMIT_ADDR_OVWRT_MASK |  \                                     XEM_ECR_UNICAST_ENABLE_MASK |   \                                     XEM_ECR_BROAD_ENABLE_MASK)#define XEM_IFGP_RESET_STATE        0x82000000UL#define XEM_SAH_RESET_STATE         0UL#define XEM_SAL_RESET_STATE         0UL#define XEM_MGTCR_RESET_STATE       XEM_MGTCR_RW_NOT_MASK#define XEM_MGTDR_RESET_STATE       0UL/* * Constants used for the loopback test */#define XEM_MAX_FRAME_SIZE_IN_WORDS ((XEM_MAX_FRAME_SIZE / sizeof(Xuint32)) + 1)#define XEM_LOOP_SEND_FRAME_SIZE    70#define XEM_LOOP_RECV_FRAME_SIZE    (XEM_LOOP_SEND_FRAME_SIZE + XEM_TRL_SIZE)#define XEM_LOOP_DATA_SIZE          (XEM_LOOP_SEND_FRAME_SIZE - XEM_HDR_SIZE)/**************************** Type Definitions *******************************//***************** Macros (Inline Functions) Definitions *********************//************************** Function Prototypes ******************************/static XStatus LoopbackTest(XEmac *InstancePtr);/************************** Variable Definitions *****************************//* Buffer used for loopback */static Xuint32 SendFrame[XEM_MAX_FRAME_SIZE_IN_WORDS];static Xuint32 RecvFrame[XEM_MAX_FRAME_SIZE_IN_WORDS];/*****************************************************************************//**** Performs a self-test on the Ethernet device.  The test includes:*   - Run self-test on DMA channel, FIFO, and IPIF components*   - Reset the Ethernet device, check its registers for proper reset values,*     and run an internal loopback test on the device. The internal loopback*     uses the device in polled mode.** This self-test is destructive. On successful completion, the device is reset* and returned to its default configuration. The caller is responsible for* re-configuring the device after the self-test is run, and starting it when* ready to send and receive frames.** It should be noted that data caching must be disabled when this function is* called because the DMA self-test uses two local buffers (on the stack) for* the transfer test.** @param InstancePtr is a pointer to the XEmac instance to be worked on.** @return** <pre>*   XST_SUCCESS                    Self-test was successful*   XST_PFIFO_BAD_REG_VALUE        FIFO failed register self-test*   XST_DMA_TRANSFER_ERROR         DMA failed data transfer self-test*   XST_DMA_RESET_REGISTER_ERROR   DMA control register value was incorrect*                                  after a reset*   XST_REGISTER_ERROR             Ethernet failed register reset test*   XST_LOOPBACK_ERROR             Internal loopback failed*   XST_IPIF_REG_WIDTH_ERROR       An invalid register width was passed into*                                  the function*   XST_IPIF_RESET_REGISTER_ERROR  The value of a register at reset was invalid*   XST_IPIF_DEVICE_STATUS_ERROR   A write to the device status register did*                                  not read back correctly*   XST_IPIF_DEVICE_ACK_ERROR      A bit in the device status register did not*                                  reset when acked*   XST_IPIF_DEVICE_ENABLE_ERROR   The device interrupt enable register was not*                                  updated correctly by the hardware when other*                                  registers were written to*   XST_IPIF_IP_STATUS_ERROR       A write to the IP interrupt status*                                  register did not read back correctly*   XST_IPIF_IP_ACK_ERROR          One or more bits in the IP status*                                  register did not reset when acked*   XST_IPIF_IP_ENABLE_ERROR       The IP interrupt enable register*                                  was not updated correctly when other*                                  registers were written to* </pre>** @note** This function makes use of options-related functions, and the XEmac_PollSend()* and XEmac_PollRecv() functions.* <br><br>* Because this test uses the PollSend function for its loopback testing, there* is the possibility that this function will not return if the hardware is* broken (i.e., it never sets the status bit indicating that transmission is* done). If this is of concern to the user, the user should provide protection* from this problem - perhaps by using a different timer thread to monitor the* self-test thread.*******************************************************************************/XStatus XEmac_SelfTest(XEmac *InstancePtr){    XStatus Result;    Xuint32 Register;    XASSERT_NONVOID(InstancePtr != XNULL);    XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);    /*     * Run self-test on the DMA (if configured) and FIFO channels     */    if (XEmac_mIsDma(InstancePtr))    {        Result = XDmaChannel_SelfTest(&InstancePtr->RecvChannel);        if (Result != XST_SUCCESS)        {            return Result;        }        Result = XDmaChannel_SelfTest(&InstancePtr->SendChannel);        if (Result != XST_SUCCESS)        {            return Result;        }    }    Result = XPacketFifoV200a_SelfTest(&InstancePtr->RecvFifo, XPF_V200A_READ_FIFO_TYPE);    if (Result != XST_SUCCESS)    {        return Result;    }    Result = XPacketFifoV200a_SelfTest(&InstancePtr->SendFifo, XPF_V200A_WRITE_FIFO_TYPE);    if (Result != XST_SUCCESS)    {        return Result;    }    /*     * Run the IPIF self-test     */    Result = XIpIfV123b_SelfTest(InstancePtr->BaseAddress, XEM_IPIF_IP_INTR_COUNT);    if (Result != XST_SUCCESS)    {        return Result;    }    /*     * Reset the Ethernet MAC to leave it in a known good state     */    XEmac_Reset(InstancePtr);    /*     * All the MAC registers should be in their default state right now. The     * registers we care about are the non-zero reset values and the     * station addresses.     */    Register = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET);    if (Register != XEM_ECR_RESET_STATE)    {        return XST_REGISTER_ERROR;    }    Register = XIo_In32(InstancePtr->BaseAddress + XEM_IFGP_OFFSET);    if (Register != XEM_IFGP_RESET_STATE)    {        return XST_REGISTER_ERROR;    }    Register = XIo_In32(InstancePtr->BaseAddress + XEM_SAH_OFFSET);    if (Register != XEM_SAH_RESET_STATE)    {        return XST_REGISTER_ERROR;    }    Register = XIo_In32(InstancePtr->BaseAddress + XEM_SAL_OFFSET);    if (Register != XEM_SAL_RESET_STATE)    {        return XST_REGISTER_ERROR;    }    Register = XIo_In32(InstancePtr->BaseAddress + XEM_MGTCR_OFFSET);    if (Register != XEM_MGTCR_RESET_STATE)    {        return XST_REGISTER_ERROR;    }    Register = XIo_In32(InstancePtr->BaseAddress + XEM_MGTDR_OFFSET);    if (Register != XEM_MGTDR_RESET_STATE)    {        return XST_REGISTER_ERROR;    }    /*     * Run an internal loopback test on the MAC.     */    Result = LoopbackTest(InstancePtr);    if (Result != XST_SUCCESS)    {        return Result;    }    /*     * Reset the Ethernet MAC to leave it in a known good state     */    XEmac_Reset(InstancePtr);    return XST_SUCCESS;}/*****************************************************************************//*** Run an internal loopback test on the MAC. This is done in polled mode with* a small (60-byte) Ethernet frame. The FCS inserted by the hardware adds four* bytes to make the total size of the frame 64 bytes.** @param InstancePtr is a pointer to the XEmac instance to be worked on.** @return** - XST_SUCCESS if loopback was performed successfully* - XST_LOOPBACK_ERROR if loopback failed** @note** None.*******************************************************************************/static XStatus LoopbackTest(XEmac *InstancePtr){    Xuint32 RecvFrameLength;    Xuint8 *FramePtr;    int Index;    Xuint32 Options;    XStatus Result;    /*     * Assemble the frame with a destination address (the station address)     * and a bogus source address (the MAC overwrites it). An Ethernet frame     * has a 14 byte header that contains a 6-byte destination address     * followed by a 6-byte source address, followed by a 2-byte type/length     * field. The frame data follows the header and can be anywhere from     * 46 bytes to 1500 bytes. Following the data is a 4-byte FCS (CRC), which     * is currently appended by the MAC.     */    FramePtr = (Xuint8 *)SendFrame;    XEmac_GetMacAddress(InstancePtr, FramePtr);    FramePtr += XEM_MAC_ADDR_SIZE;  /* get past dest address */    FramePtr += XEM_MAC_ADDR_SIZE;  /* get past source address (bogus) */    /* Set up the type/length field to a length of XEM_LOOPBACK_DATA_SIZE */    *FramePtr++ = 0;    *FramePtr++ = XEM_LOOP_DATA_SIZE;    /*     * Now fill in the data field with known values so we can verify them     * on receive.     */    for (Index = 0; Index < XEM_LOOP_DATA_SIZE; Index++)    {        *FramePtr++ = (Xuint8)Index;    }    /*     * Configure the device for loopback and polled mode     */    (void)XEmac_Stop(InstancePtr);    Options = XEmac_GetOptions(InstancePtr);    Options |= (XEM_POLLED_OPTION | XEM_LOOPBACK_OPTION);    (void)XEmac_SetOptions(InstancePtr, Options);    (void)XEmac_Start(InstancePtr);    /*     * Now send the frame, then receive it and verify its contents     */    Result = XEmac_PollSend(InstancePtr, (Xuint8 *)SendFrame,                                     XEM_LOOP_SEND_FRAME_SIZE);    if (Result == XST_SUCCESS)    {        RecvFrameLength = XEM_MAX_FRAME_SIZE;        /*         * Receive the frame. We assume the frame is already in the         * receive FIFO by this time. Otherwise we would need to loop         * on the PollRecv call since it is non-blocking.         */        Result = XEmac_PollRecv(InstancePtr, (Xuint8 *)RecvFrame,                                     &RecvFrameLength);        if (Result == XST_SUCCESS)        {            /* Verify the length */            if (RecvFrameLength != XEM_LOOP_RECV_FRAME_SIZE)            {                return XST_LOOPBACK_ERROR;            }            /* Verify the frame contents */            FramePtr = (Xuint8 *)RecvFrame;            FramePtr += XEM_HDR_SIZE;    /* get past the header */            for (Index = 0; Index < XEM_LOOP_DATA_SIZE; Index++)            {                if (*FramePtr++ != (Xuint8)Index)                {                    return XST_LOOPBACK_ERROR;                }            }        }    }    /*     * Test is finished, return the result (do not bother restoring the     * device state to what it was before the test started, since this is     * called from self-test anyway, and a reset occurs at the end.     */    return Result;}

⌨️ 快捷键说明

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