📄 eth_test.c
字号:
/*! * \file eth_test.c * \brief Test an Ethernet interface on Jamaica (MCF5445x EVB) * \version $Revision: 1.1 $ * \author Michael Norman * * This is a simple Ethernet test that uses loopback tests to verify the * proper operation of an Ethernet port. Three different loopbacks are * attempted: * - Internal FEC loopback. This is a sanity check to make sure the FEC is * working properly * - PHY loopback. This checks the connectivity between the FEC and the PHY * - Cable loopback. This test requires that an Ethernet "plug" cable is * inserted into the RJ45 connector. An external link partner that echoes * the packet could also be used. */ #include "common.h"#include "queue.h"#include "nbuf.h"#include "eth.h"#include "fecbd.h"#include "mii.h"#include "eth_phy.h"#include "m54451evb_tests.h"/********************************************************************//* Buffer Descriptors -- must be aligned on a 4-byte boundary but a * 16-byte boundary is recommended. To avoid playing games with the * various compilers and their different extension to ANSI C, these * buffers are aligned by allocating an extra line of data and * adjusting the pointers in nbuf_init(). */uint8 unaligned_txbd[(sizeof(NBUF) * 3) + 15];uint8 unaligned_rxbd[(sizeof(NBUF) * 3) + 15];#define Rx 1#define Tx 0/* Buffer sizes in bytes (must be divisible by 16) */#define RX_BUFFER_SIZE 576#define TX_BUFFER_SIZE 576/* Number of Receive and Transmit Buffers and Buffer Descriptors */#define NUM_RXBDS 3#define NUM_TXBDS 3FECBD *TxNBUF;FECBD *RxNBUF;/* Data Buffers -- must be aligned on a 16-byte boundary. To avoid * playing games with the various compilers and their different * extension to ANSI C, these buffers are aligned by allocating an * extra line of data and adjusting the pointers in nbuf_init(). */uint8 unaligned_rxbuffer[(RX_BUFFER_SIZE * 3) + 16];uint8 *TxBuffer;uint8 *RxBuffer;/* Data to be transmitted */const int packet[] = { 0x00CFCFCF,0xCF0100CF,0xCFCFCF01,0x3a00eeff, 0x55555555,0x66666666,0x77777777,0x88888888, 0x99999999,0x00000000,0xaaaaaaaa,0xbbbbbbbb, 0xcccccccc,0xdddddddd,0xeeeeeeee,0xffffffff, /* 64 Bytes */ 0x11111111,0x22222222,0x33333333,0x44444444, 0x55555555,0x66666666,0x77777777,0x88888888, 0x12345678,0x90abcdef,0x78162435,0xbd895b14, 0xcccccccc,0xdddddddd,0xeeeeeeee,0xffffffff, /* 128 Bytes */ 0x11111111,0x22222222,0x33333333,0x44444444, 0x55555555,0x66666666,0x77777777,0x88888888, 0x99999999,0x00000000,0xaaaaaaaa,0xbbbbbbbb, 0xcccccccc,0xdddddddd,0xeeeeeeee,0xffffffff, /* 192 Bytes */ 0x99a152a3,0x54a556a7,0x58a95aab,0x5cad5eaf, 0x99a152a3,0x54a556a7,0x58a95aab,0x5cad5eaf, 0x99a152a3,0x54a556a7,0x58a95aab,0x5cad5eaf, 0x99a152a3,0x54a556a7,0x58a95aab,0x5cad5eaf /* 256 Bytes */};/********************************************************************//*! * \brief Simple Ethernet test * \param n FEC channel to test * \return 0 if all tests were successful * 1 if cable loopback failed * 2 if PHY loopback failed * 3 if internal loopback all failed * * \warning Assumes running on Jamaica platform with dual-FEC enabled MCF5445x */inteth_test(int n){ int i, j, k, retval; ASSERT(n >= 0 && n <= 1); ASSERT(sizeof(packet) <= RX_BUFFER_SIZE); /* Reset the FEC */ MCF_FEC_ECR(n) = MCF_FEC_ECR_RESET; /* Enable FEC RMII pin functions */ if (n == 0) { MCF_GPIO_PAR_FEC = MCF_GPIO_PAR_FEC & MCF_GPIO_PAR_FEC_FEC0_MASK | MCF_GPIO_PAR_FEC_FEC0_RMII_GPIO; } else { MCF_GPIO_PAR_FEC = MCF_GPIO_PAR_FEC & MCF_GPIO_PAR_FEC_FEC1_MASK | MCF_GPIO_PAR_FEC_FEC1_RMII_GPIO; } MCF_GPIO_PAR_FECI2C |= 0 | MCF_GPIO_PAR_FECI2C_MDC0_MDC0 | MCF_GPIO_PAR_FECI2C_MDIO0_MDIO0; /* initialize the buffers and buffer descriptors */ TxNBUF = (FECBD *)((uint32)(unaligned_txbd + 15) & 0xFFFFFFF0); RxNBUF = (FECBD *)((uint32)(unaligned_rxbd + 15) & 0xFFFFFFF0); RxBuffer = (uint8 *)((uint32)(unaligned_rxbuffer + 15) & 0xFFFFFFF0); /* Initialize receive descriptor ring */ for (i = 0; i < 3; i++) { RxNBUF[i].status = RX_BD_E; RxNBUF[i].length = 0; RxNBUF[i].data = &RxBuffer[i * RX_BUFFER_SIZE]; } /* Set the Wrap bit on the last one in the ring */ RxNBUF[2].status |= RX_BD_W; /* Zero out the receive buffers so we can insure proper reception later */ for (i = 0; i < sizeof(packet); i++) RxNBUF[0].data[i] = 0; /* Initialize transmit descriptor ring */ for (i = 0; i < 3; i++) { TxNBUF[i].status = TX_BD_L | TX_BD_TC; TxNBUF[i].length = sizeof(packet); TxNBUF[i].data = (uint8 *)packet; } /* Set the Wrap bit on the last one in the ring */ TxNBUF[2].status |= TX_BD_W; /* Set the source address for the controller */ MCF_FEC_PALR(n) = 0x00CFCFCF; MCF_FEC_PAUR(n) = 0xCF010000; MCF_FEC_IALR(n) = 0x00000000; MCF_FEC_IAUR(n) = 0x00000000; MCF_FEC_GALR(n) = 0x00000000; MCF_FEC_GAUR(n) = 0x00000000; /* Set Receive Buffer Size */ MCF_FEC_EMRBR(n) = (uint16)RX_BUFFER_SIZE; /* Point to the start of the circular Rx buffer descriptor queue */ MCF_FEC_ERDSR(n) = (uint32)RxNBUF; /* Point to the start of the circular Tx buffer descriptor queue */ MCF_FEC_ETDSR(n) = (uint32)TxNBUF; MCF_FEC_RCR(n) = 0 |MCF_FEC_RCR_MAX_FL(1518) | MCF_FEC_RCR_MII_MODE | MCF_FEC_RCR_PROM; MCF_FEC_TCR(n) = 0 | MCF_FEC_TCR_FDEN; /* Make sure the FEC knows we are trying to put it into RMII mode */ ASSERT(MCF_FEC_RCR(n) & MCF_FEC_RCR_RMII_MODE); /* Enable FEC */ MCF_FEC_ECR(n) |= MCF_FEC_ECR_ETHER_EN; /* Initialize the MII channel */ mii_init(FSYS_MHZ); /* Tell the FEC that empty Rx buffers have been produced */ MCF_FEC_RDAR(n) = MCF_FEC_RDAR_R_DES_ACTIVE; for (j = 0; j < 3; j++) { if (j == 0) { /* Turn on internal loopback */ MCF_FEC_RCR(n) |= MCF_FEC_RCR_LOOP; /* Set the return value in case of failure */ retval = (n == 0) ? ETH0_FAIL_FEC_LOOP : ETH1_FAIL_FEC_LOOP; } else if (j == 1) { /* Turn off internal loopback */ MCF_FEC_RCR(n) &= ~MCF_FEC_RCR_LOOP; /* Set the return value in case of failure */ retval = (n == 0) ? ETH0_FAIL_PHY_LOOP : ETH1_FAIL_PHY_LOOP; /* Put the PHY in loopback mode */ if (eth_phy_manual(n, MII_100BASE_TX, MII_FDX, TRUE)) return retval; } else /* j = 2 */ { /* Set the return value in case of failure */ retval = (n == 0) ? ETH0_FAIL_CBL_LOOP : ETH1_FAIL_CBL_LOOP; /* Put the PHY in normal 100/full mode */ if (eth_phy_manual(n, MII_100BASE_TX, MII_FDX, FALSE)) return retval; } /* Mark packet as ready to send */ TxNBUF[j].status |= TX_BD_R; /* Indicate to FEC that transmit buffer is ready to send */ MCF_FEC_TDAR(n) = MCF_FEC_TDAR_X_DES_ACTIVE; for (k = 0; k < 1000000; k++) { if (MCF_FEC_EIR(n) & MCF_FEC_EIR_RXF) { MCF_FEC_EIR(n) = MCF_FEC_EIR_RXF; break; } } /* Check for timeout */ if (k == 1000000) { return retval; } /* Check for data corruption */ for (k = 0; k < sizeof(packet); k += 4) { if (TxNBUF[j].data[k] != RxNBUF[j].data[k]) { return retval; } } } /* passed all tests */ return (n == 0) ? ETH0_PASS : ETH1_PASS;}/********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -