diff options
Diffstat (limited to 'post/ether.c')
-rw-r--r-- | post/ether.c | 631 |
1 files changed, 0 insertions, 631 deletions
diff --git a/post/ether.c b/post/ether.c deleted file mode 100644 index 8c87b59..0000000 --- a/post/ether.c +++ /dev/null @@ -1,631 +0,0 @@ -/* - * (C) Copyright 2002 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> - -/* - * Ethernet test - * - * The Serial Communication Controllers (SCC) listed in ctlr_list array below - * are tested in the loopback ethernet mode. - * The controllers are configured accordingly and several packets - * are transmitted. The configurable test parameters are: - * MIN_PACKET_LENGTH - minimum size of packet to transmit - * MAX_PACKET_LENGTH - maximum size of packet to transmit - * TEST_NUM - number of tests - */ - -#ifdef CONFIG_POST - -#include <post.h> -#if CONFIG_POST & CFG_POST_ETHER -#if defined(CONFIG_8xx) -#include <commproc.h> -#elif defined(CONFIG_MPC8260) -#include <asm/cpm_8260.h> -#else -#error "Apparently a bad configuration, please fix." -#endif - -#include <command.h> -#include <net.h> -#include <serial.h> - -DECLARE_GLOBAL_DATA_PTR; - -#define MIN_PACKET_LENGTH 64 -#define MAX_PACKET_LENGTH 256 -#define TEST_NUM 1 - -#define CTLR_SCC 0 - -extern void spi_init_f (void); -extern void spi_init_r (void); - -/* The list of controllers to test */ -#if defined(CONFIG_MPC823) -static int ctlr_list[][2] = { {CTLR_SCC, 1} }; -#else -static int ctlr_list[][2] = { }; -#endif - -#define CTRL_LIST_SIZE (sizeof(ctlr_list) / sizeof(ctlr_list[0])) - -static struct { - void (*init) (int index); - void (*halt) (int index); - int (*send) (int index, volatile void *packet, int length); - int (*recv) (int index, void *packet, int length); -} ctlr_proc[1]; - -static char *ctlr_name[1] = { "SCC" }; - -/* Ethernet Transmit and Receive Buffers */ -#define DBUF_LENGTH 1520 - -#define TX_BUF_CNT 2 - -#define TOUT_LOOP 100 - -static char txbuf[DBUF_LENGTH]; - -static uint rxIdx; /* index of the current RX buffer */ -static uint txIdx; /* index of the current TX buffer */ - -/* - * SCC Ethernet Tx and Rx buffer descriptors allocated at the - * immr->udata_bd address on Dual-Port RAM - * Provide for Double Buffering - */ - -typedef volatile struct CommonBufferDescriptor { - cbd_t rxbd[PKTBUFSRX]; /* Rx BD */ - cbd_t txbd[TX_BUF_CNT]; /* Tx BD */ -} RTXBD; - -static RTXBD *rtx; - - /* - * SCC callbacks - */ - -static void scc_init (int scc_index) -{ - bd_t *bd = gd->bd; - - static int proff[] = - { PROFF_SCC1, PROFF_SCC2, PROFF_SCC3, PROFF_SCC4 }; - static unsigned int cpm_cr[] = - { CPM_CR_CH_SCC1, CPM_CR_CH_SCC2, CPM_CR_CH_SCC3, -CPM_CR_CH_SCC4 }; - - int i; - scc_enet_t *pram_ptr; - - volatile immap_t *immr = (immap_t *) CFG_IMMR; - - immr->im_cpm.cp_scc[scc_index].scc_gsmrl &= - ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - -#if defined(CONFIG_FADS) -#if defined(CONFIG_MPC860T) || defined(CONFIG_MPC86xADS) - /* The FADS860T and MPC86xADS don't use the MODEM_EN or DATA_VOICE signals. */ - *((uint *) BCSR4) &= ~BCSR4_ETHLOOP; - *((uint *) BCSR4) |= BCSR4_TFPLDL | BCSR4_TPSQEL; - *((uint *) BCSR1) &= ~BCSR1_ETHEN; -#else - *((uint *) BCSR4) &= ~(BCSR4_ETHLOOP | BCSR4_MODEM_EN); - *((uint *) BCSR4) |= BCSR4_TFPLDL | BCSR4_TPSQEL | BCSR4_DATA_VOICE; - *((uint *) BCSR1) &= ~BCSR1_ETHEN; -#endif -#endif - - pram_ptr = (scc_enet_t *) & (immr->im_cpm.cp_dparam[proff[scc_index]]); - - rxIdx = 0; - txIdx = 0; - -#ifdef CFG_ALLOC_DPRAM - rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + - dpram_alloc_align (sizeof (RTXBD), 8)); -#else - rtx = (RTXBD *) (immr->im_cpm.cp_dpmem + CPM_SCC_BASE); -#endif - -#if 0 - -#if (defined(PA_ENET_RXD) && defined(PA_ENET_TXD)) - /* Configure port A pins for Txd and Rxd. - */ - immr->im_ioport.iop_papar |= (PA_ENET_RXD | PA_ENET_TXD); - immr->im_ioport.iop_padir &= ~(PA_ENET_RXD | PA_ENET_TXD); - immr->im_ioport.iop_paodr &= ~PA_ENET_TXD; -#elif (defined(PB_ENET_RXD) && defined(PB_ENET_TXD)) - /* Configure port B pins for Txd and Rxd. - */ - immr->im_cpm.cp_pbpar |= (PB_ENET_RXD | PB_ENET_TXD); - immr->im_cpm.cp_pbdir &= ~(PB_ENET_RXD | PB_ENET_TXD); - immr->im_cpm.cp_pbodr &= ~PB_ENET_TXD; -#else -#error Configuration Error: exactly ONE of PA_ENET_[RT]XD, PB_ENET_[RT]XD must be defined -#endif - -#if defined(PC_ENET_LBK) - /* Configure port C pins to disable External Loopback - */ - immr->im_ioport.iop_pcpar &= ~PC_ENET_LBK; - immr->im_ioport.iop_pcdir |= PC_ENET_LBK; - immr->im_ioport.iop_pcso &= ~PC_ENET_LBK; - immr->im_ioport.iop_pcdat &= ~PC_ENET_LBK; /* Disable Loopback */ -#endif /* PC_ENET_LBK */ - - /* Configure port C pins to enable CLSN and RENA. - */ - immr->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA); - immr->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA); - immr->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA); - - /* Configure port A for TCLK and RCLK. - */ - immr->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK); - immr->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK); - - /* - * Configure Serial Interface clock routing -- see section 16.7.5.3 - * First, clear all SCC bits to zero, then set the ones we want. - */ - - immr->im_cpm.cp_sicr &= ~SICR_ENET_MASK; - immr->im_cpm.cp_sicr |= SICR_ENET_CLKRT; -#else - /* - * SCC2 receive clock is BRG2 - * SCC2 transmit clock is BRG3 - */ - immr->im_cpm.cp_brgc2 = 0x0001000C; - immr->im_cpm.cp_brgc3 = 0x0001000C; - - immr->im_cpm.cp_sicr &= ~0x00003F00; - immr->im_cpm.cp_sicr |= 0x00000a00; -#endif /* 0 */ - - - /* - * Initialize SDCR -- see section 16.9.23.7 - * SDMA configuration register - */ - immr->im_siu_conf.sc_sdcr = 0x01; - - - /* - * Setup SCC Ethernet Parameter RAM - */ - - pram_ptr->sen_genscc.scc_rfcr = 0x18; /* Normal Operation and Mot byte ordering */ - pram_ptr->sen_genscc.scc_tfcr = 0x18; /* Mot byte ordering, Normal access */ - - pram_ptr->sen_genscc.scc_mrblr = DBUF_LENGTH; /* max. ET package len 1520 */ - - pram_ptr->sen_genscc.scc_rbase = (unsigned int) (&rtx->rxbd[0]); /* Set RXBD tbl start at Dual Port */ - pram_ptr->sen_genscc.scc_tbase = (unsigned int) (&rtx->txbd[0]); /* Set TXBD tbl start at Dual Port */ - - /* - * Setup Receiver Buffer Descriptors (13.14.24.18) - * Settings: - * Empty, Wrap - */ - - for (i = 0; i < PKTBUFSRX; i++) { - rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; - rtx->rxbd[i].cbd_datlen = 0; /* Reset */ - rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i]; - } - - rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; - - /* - * Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19) - * Settings: - * Add PADs to Short FRAMES, Wrap, Last, Tx CRC - */ - - for (i = 0; i < TX_BUF_CNT; i++) { - rtx->txbd[i].cbd_sc = - (BD_ENET_TX_PAD | BD_ENET_TX_LAST | BD_ENET_TX_TC); - rtx->txbd[i].cbd_datlen = 0; /* Reset */ - rtx->txbd[i].cbd_bufaddr = (uint) (&txbuf[0]); - } - - rtx->txbd[TX_BUF_CNT - 1].cbd_sc |= BD_ENET_TX_WRAP; - - /* - * Enter Command: Initialize Rx Params for SCC - */ - - do { /* Spin until ready to issue command */ - __asm__ ("eieio"); - } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG); - /* Issue command */ - immr->im_cpm.cp_cpcr = - ((CPM_CR_INIT_RX << 8) | (cpm_cr[scc_index] << 4) | - CPM_CR_FLG); - do { /* Spin until command processed */ - __asm__ ("eieio"); - } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG); - - /* - * Ethernet Specific Parameter RAM - * see table 13-16, pg. 660, - * pg. 681 (example with suggested settings) - */ - - pram_ptr->sen_cpres = ~(0x0); /* Preset CRC */ - pram_ptr->sen_cmask = 0xdebb20e3; /* Constant Mask for CRC */ - pram_ptr->sen_crcec = 0x0; /* Error Counter CRC (unused) */ - pram_ptr->sen_alec = 0x0; /* Alignment Error Counter (unused) */ - pram_ptr->sen_disfc = 0x0; /* Discard Frame Counter (unused) */ - pram_ptr->sen_pads = 0x8888; /* Short Frame PAD Characters */ - - pram_ptr->sen_retlim = 15; /* Retry Limit Threshold */ - pram_ptr->sen_maxflr = 1518; /* MAX Frame Length Register */ - pram_ptr->sen_minflr = 64; /* MIN Frame Length Register */ - - pram_ptr->sen_maxd1 = DBUF_LENGTH; /* MAX DMA1 Length Register */ - pram_ptr->sen_maxd2 = DBUF_LENGTH; /* MAX DMA2 Length Register */ - - pram_ptr->sen_gaddr1 = 0x0; /* Group Address Filter 1 (unused) */ - pram_ptr->sen_gaddr2 = 0x0; /* Group Address Filter 2 (unused) */ - pram_ptr->sen_gaddr3 = 0x0; /* Group Address Filter 3 (unused) */ - pram_ptr->sen_gaddr4 = 0x0; /* Group Address Filter 4 (unused) */ - -#define ea bd->bi_enetaddr - pram_ptr->sen_paddrh = (ea[5] << 8) + ea[4]; - pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2]; - pram_ptr->sen_paddrl = (ea[1] << 8) + ea[0]; -#undef ea - - pram_ptr->sen_pper = 0x0; /* Persistence (unused) */ - pram_ptr->sen_iaddr1 = 0x0; /* Individual Address Filter 1 (unused) */ - pram_ptr->sen_iaddr2 = 0x0; /* Individual Address Filter 2 (unused) */ - pram_ptr->sen_iaddr3 = 0x0; /* Individual Address Filter 3 (unused) */ - pram_ptr->sen_iaddr4 = 0x0; /* Individual Address Filter 4 (unused) */ - pram_ptr->sen_taddrh = 0x0; /* Tmp Address (MSB) (unused) */ - pram_ptr->sen_taddrm = 0x0; /* Tmp Address (unused) */ - pram_ptr->sen_taddrl = 0x0; /* Tmp Address (LSB) (unused) */ - - /* - * Enter Command: Initialize Tx Params for SCC - */ - - do { /* Spin until ready to issue command */ - __asm__ ("eieio"); - } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG); - /* Issue command */ - immr->im_cpm.cp_cpcr = - ((CPM_CR_INIT_TX << 8) | (cpm_cr[scc_index] << 4) | - CPM_CR_FLG); - do { /* Spin until command processed */ - __asm__ ("eieio"); - } while (immr->im_cpm.cp_cpcr & CPM_CR_FLG); - - /* - * Mask all Events in SCCM - we use polling mode - */ - immr->im_cpm.cp_scc[scc_index].scc_sccm = 0; - - /* - * Clear Events in SCCE -- Clear bits by writing 1's - */ - - immr->im_cpm.cp_scc[scc_index].scc_scce = ~(0x0); - - - /* - * Initialize GSMR High 32-Bits - * Settings: Normal Mode - */ - - immr->im_cpm.cp_scc[scc_index].scc_gsmrh = 0; - - /* - * Initialize GSMR Low 32-Bits, but do not Enable Transmit/Receive - * Settings: - * TCI = Invert - * TPL = 48 bits - * TPP = Repeating 10's - * LOOP = Loopback - * MODE = Ethernet - */ - - immr->im_cpm.cp_scc[scc_index].scc_gsmrl = (SCC_GSMRL_TCI | - SCC_GSMRL_TPL_48 | - SCC_GSMRL_TPP_10 | - SCC_GSMRL_DIAG_LOOP | - SCC_GSMRL_MODE_ENET); - - /* - * Initialize the DSR -- see section 13.14.4 (pg. 513) v0.4 - */ - - immr->im_cpm.cp_scc[scc_index].scc_dsr = 0xd555; - - /* - * Initialize the PSMR - * Settings: - * CRC = 32-Bit CCITT - * NIB = Begin searching for SFD 22 bits after RENA - * LPB = Loopback Enable (Needed when FDE is set) - */ - immr->im_cpm.cp_scc[scc_index].scc_psmr = SCC_PSMR_ENCRC | - SCC_PSMR_NIB22 | SCC_PSMR_LPB; - -#if 0 - /* - * Configure Ethernet TENA Signal - */ - -#if (defined(PC_ENET_TENA) && !defined(PB_ENET_TENA)) - immr->im_ioport.iop_pcpar |= PC_ENET_TENA; - immr->im_ioport.iop_pcdir &= ~PC_ENET_TENA; -#elif (defined(PB_ENET_TENA) && !defined(PC_ENET_TENA)) - immr->im_cpm.cp_pbpar |= PB_ENET_TENA; - immr->im_cpm.cp_pbdir |= PB_ENET_TENA; -#else -#error Configuration Error: exactly ONE of PB_ENET_TENA, PC_ENET_TENA must be defined -#endif - -#if defined(CONFIG_ADS) && defined(CONFIG_MPC860) - /* - * Port C is used to control the PHY,MC68160. - */ - immr->im_ioport.iop_pcdir |= - (PC_ENET_ETHLOOP | PC_ENET_TPFLDL | PC_ENET_TPSQEL); - - immr->im_ioport.iop_pcdat |= PC_ENET_TPFLDL; - immr->im_ioport.iop_pcdat &= ~(PC_ENET_ETHLOOP | PC_ENET_TPSQEL); - *((uint *) BCSR1) &= ~BCSR1_ETHEN; -#endif /* MPC860ADS */ - -#if defined(CONFIG_AMX860) - /* - * Port B is used to control the PHY,MC68160. - */ - immr->im_cpm.cp_pbdir |= - (PB_ENET_ETHLOOP | PB_ENET_TPFLDL | PB_ENET_TPSQEL); - - immr->im_cpm.cp_pbdat |= PB_ENET_TPFLDL; - immr->im_cpm.cp_pbdat &= ~(PB_ENET_ETHLOOP | PB_ENET_TPSQEL); - - immr->im_ioport.iop_pddir |= PD_ENET_ETH_EN; - immr->im_ioport.iop_pddat &= ~PD_ENET_ETH_EN; -#endif /* AMX860 */ - -#endif /* 0 */ - -#ifdef CONFIG_RPXCLASSIC - *((uchar *) BCSR0) &= ~BCSR0_ETHLPBK; - *((uchar *) BCSR0) |= (BCSR0_ETHEN | BCSR0_COLTEST | BCSR0_FULLDPLX); -#endif - -#ifdef CONFIG_RPXLITE - *((uchar *) BCSR0) |= BCSR0_ETHEN; -#endif - -#ifdef CONFIG_MBX - board_ether_init (); -#endif - - /* - * Set the ENT/ENR bits in the GSMR Low -- Enable Transmit/Receive - */ - - immr->im_cpm.cp_scc[scc_index].scc_gsmrl |= - (SCC_GSMRL_ENR | SCC_GSMRL_ENT); - - /* - * Work around transmit problem with first eth packet - */ -#if defined (CONFIG_FADS) - udelay (10000); /* wait 10 ms */ -#elif defined (CONFIG_AMX860) || defined(CONFIG_RPXCLASSIC) - udelay (100000); /* wait 100 ms */ -#endif -} - -static void scc_halt (int scc_index) -{ - volatile immap_t *immr = (immap_t *) CFG_IMMR; - - immr->im_cpm.cp_scc[scc_index].scc_gsmrl &= - ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); - immr->im_ioport.iop_pcso &= ~(PC_ENET_CLSN | PC_ENET_RENA); -} - -static int scc_send (int index, volatile void *packet, int length) -{ - int i, j = 0; - - while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j < TOUT_LOOP)) { - udelay (1); /* will also trigger Wd if needed */ - j++; - } - if (j >= TOUT_LOOP) - printf ("TX not ready\n"); - rtx->txbd[txIdx].cbd_bufaddr = (uint) packet; - rtx->txbd[txIdx].cbd_datlen = length; - rtx->txbd[txIdx].cbd_sc |= - (BD_ENET_TX_READY | BD_ENET_TX_LAST | BD_ENET_TX_WRAP); - while ((rtx->txbd[txIdx].cbd_sc & BD_ENET_TX_READY) && (j < TOUT_LOOP)) { - udelay (1); /* will also trigger Wd if needed */ - j++; - } - if (j >= TOUT_LOOP) - printf ("TX timeout\n"); - i = (rtx->txbd[txIdx]. - cbd_sc & BD_ENET_TX_STATS) /* return only status bits */ ; - return i; -} - -static int scc_recv (int index, void *packet, int max_length) -{ - int length = -1; - - if (rtx->rxbd[rxIdx].cbd_sc & BD_ENET_RX_EMPTY) { - goto Done; /* nothing received */ - } - - if (!(rtx->rxbd[rxIdx].cbd_sc & 0x003f)) { - length = rtx->rxbd[rxIdx].cbd_datlen - 4; - memcpy (packet, - (void *) (NetRxPackets[rxIdx]), - length < max_length ? length : max_length); - } - - /* Give the buffer back to the SCC. */ - rtx->rxbd[rxIdx].cbd_datlen = 0; - - /* wrap around buffer index when necessary */ - if ((rxIdx + 1) >= PKTBUFSRX) { - rtx->rxbd[PKTBUFSRX - 1].cbd_sc = - (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY); - rxIdx = 0; - } else { - rtx->rxbd[rxIdx].cbd_sc = BD_ENET_RX_EMPTY; - rxIdx++; - } - -Done: - return length; -} - - /* - * Test routines - */ - -static void packet_fill (char *packet, int length) -{ - char c = (char) length; - int i; - - packet[0] = 0xFF; - packet[1] = 0xFF; - packet[2] = 0xFF; - packet[3] = 0xFF; - packet[4] = 0xFF; - packet[5] = 0xFF; - - for (i = 6; i < length; i++) { - packet[i] = c++; - } -} - -static int packet_check (char *packet, int length) -{ - char c = (char) length; - int i; - - for (i = 6; i < length; i++) { - if (packet[i] != c++) - return -1; - } - - return 0; -} - -static int test_ctlr (int ctlr, int index) -{ - int res = -1; - char packet_send[MAX_PACKET_LENGTH]; - char packet_recv[MAX_PACKET_LENGTH]; - int length; - int i; - int l; - - ctlr_proc[ctlr].init (index); - - for (i = 0; i < TEST_NUM; i++) { - for (l = MIN_PACKET_LENGTH; l <= MAX_PACKET_LENGTH; l++) { - packet_fill (packet_send, l); - - ctlr_proc[ctlr].send (index, packet_send, l); - - length = ctlr_proc[ctlr].recv (index, packet_recv, - MAX_PACKET_LENGTH); - - if (length != l || packet_check (packet_recv, length) < 0) { - goto Done; - } - } - } - - res = 0; - -Done: - - ctlr_proc[ctlr].halt (index); - - /* - * SCC2 Ethernet parameter RAM space overlaps - * the SPI parameter RAM space. So we need to restore - * the SPI configuration after SCC2 ethernet test. - */ -#if defined(CONFIG_SPI) - if (ctlr == CTLR_SCC && index == 1) { - spi_init_f (); - spi_init_r (); - } -#endif - - if (res != 0) { - post_log ("ethernet %s%d test failed\n", ctlr_name[ctlr], - index + 1); - } - - return res; -} - -int ether_post_test (int flags) -{ - int res = 0; - int i; - - ctlr_proc[CTLR_SCC].init = scc_init; - ctlr_proc[CTLR_SCC].halt = scc_halt; - ctlr_proc[CTLR_SCC].send = scc_send; - ctlr_proc[CTLR_SCC].recv = scc_recv; - - for (i = 0; i < CTRL_LIST_SIZE; i++) { - if (test_ctlr (ctlr_list[i][0], ctlr_list[i][1]) != 0) { - res = -1; - } - } - -#if !defined(CONFIG_8xx_CONS_NONE) - serial_reinit_all (); -#endif - return res; -} - -#endif /* CONFIG_POST & CFG_POST_ETHER */ - -#endif /* CONFIG_POST */ |