/* * (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 /* * 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 #include #include #if CONFIG_POST & CFG_POST_ETHER #define MIN_PACKET_LENGTH 64 #define MAX_PACKET_LENGTH 1500 #define TEST_NUM 5 #define VERBOSE 1 /* * Test routines */ static void packet_set_address(char * packet, char *enetaddr) { char *tmp, *end; int i; tmp = enetaddr; if (tmp) { for (i = 0; i < 6; i++) { packet[i] = tmp ? simple_strtoul(tmp, &end, 16) : 0; if (tmp) tmp = (*end) ? end+1 : end; } } else { for (i = 0; i < 6; i++) { packet[i] = 0xFF; } } } static void packet_fill (char *packet, int length) { char c = (char) length; int i; 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; } int ether_post_test(void) { DECLARE_GLOBAL_DATA_PTR; int res = 0; char packet_send[MAX_PACKET_LENGTH]; char packet_recv[MAX_PACKET_LENGTH]; int i,l,length; int timeout; struct eth_device *dev= eth_get_dev(); dev->init(dev, gd->bd); packet_set_address(packet_send, getenv("ethaddr")); for ( i = 0; i < TEST_NUM; i++) { #ifdef VERBOSE printf("\n\tDoing ethernet test(%d) ",i); #endif for (l = MIN_PACKET_LENGTH; l <= MAX_PACKET_LENGTH; l++) { packet_fill (packet_send, l); #ifdef VERBOSE if(((l+1)&0x3f) == 0) printf("."); #endif if (dev->send(dev, packet_send, l) != 0) { post_log("Error sending packet.\n",l); res = 1; break; } timeout = 5000; do { udelay(1000); length = dev->recv_packet(dev, packet_recv); if(timeout-- == 0) { post_log("Timeout receiving packet.\n"); res = 1; break; } }while(length == 0); if((length != l) || (packet_check (packet_recv, length) < 0)){ post_log("Packet rejected: (%d) bytes transmitted (%d) bytes received.\n",l,length); res = 1; break; } if(res) break; } } dev->halt(dev); return res; } #endif /* CONFIG_POST & CFG_POST_ETHER */ #endif /* CONFIG_POST */