[U-Boot] Ethernet HW loopack test

Guy Morand Morand at telecontrol.ch
Tue Dec 21 15:43:48 CET 2010


Hello,

I'm trying to write an U-Boot command to ping the other interface on my platform. This is to test the hardware at production, the ping must hit the wire. I got deeply inspired from this patch:
http://lists.denx.de/pipermail/u-boot/2005-March/009317.html

What changes is that I really want to ping the other interface with a cross cable and not using a special "home made" device ... The problem is when I send the ping, it is the same interface that answers (the one that sent the ping), this is not what I want. I thought by changing the destination MAC address in the packet and initializing it, the other interface should answer by itself. Actually this is not the case...

I know a lot of improvement can be done but at the moment I just trying to make it work, this is why I let a lot of "debug" code and messages...
------------------ Here is some code I wrote in net/net.c ------------------
void
NetReceive(volatile uchar * inpkt, int len)
{
     ...
     switch (x) {
     case PROT_ARP:
          ...
     case PROT_TEST:
          answerToEthloopTest(pkt, et->et_dest, et->et_src, len);
          break;
     ...
}
/* Prepare and send packet ... */
int EthLoopSend(void)
{
     int i;
     uchar *pkt;
     struct eth_device* thisEth = eth_get_dev_by_index(eth_get_dev_index());
     struct eth_device* other = thisEth->next;
     bd_t *bd = gd->bd;

     /* Choose the destination interface */
     if(other->init(other, bd)){
          printf("Couldn't initialize other interface, cannot perform test !\n");
          return -1;
     }

     printf("Using %s as destination device\n", other->name);
     for (i=12 ; i<ETHLOOP_LEN ; i++) {
          EtherPacket[i] = i;
     }

     /* set the other interface's MAC address as destination address */
     pkt = (uchar *)EtherPacket;
     pkt += NetSetEther (pkt, other->enetaddr, PROT_TEST);

     (void) eth_send(EtherPacket, ETHLOOP_LEN);

     return 1; /* waiting */
}

/* When no answer arrives ... */
static void EthLoopTimeout (void)
{
     eth_halt();
     NetState = NETLOOP_FAIL;  /* we did not get the reply */
}

/* The other interface answers here */
static void answerToEthloopTest(uchar *pkt, unsigned dest, unsigned src, unsigned len){
     int i;
     uchar tmp;
     pkt = (uchar *)EtherPacket;

     printf("Device %s answers ...\n", eth_get_name());  =======>>>> Why is it ETSEC 0 ??!

     // Reverse src dest MAC
     for(i = 1 ; i < 6 ; i++){
          tmp = EtherPacket[i];
          EtherPacket[i] = EtherPacket[i + 6];
          EtherPacket[i + 6] = tmp;
     }

     (void)eth_send(EtherPacket, ETHLOOP_LEN);
     eth_get_dev()->halt(eth_get_dev());
}

/* When the source interface got an answer */
static void EthLoopHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
{
     int i = 12;
     pkt = (uchar *)EtherPacket;

     for(i ; i < len ; i++){
          printf("Comparing %i with %i at index %i", pkt[i], i, i);
          if(pkt[i] != i){
                NetState = NETLOOP_FAIL;
                break;
          }
     }
}

/* Initialize the loop test */
static void EthLoopStart(void)
{
     printf ("Using %s as source device\n", eth_get_name());
     NetSetTimeout (2000, EthLoopTimeout);
     NetSetHandler (EthLoopHandler);
     EthLoopSend();
}
-------------------------- Here is the output --------------------------------------
IPSniffer=> ethloop
Speed: 10, half duplex
Using eTSEC0 as source device
Speed: 10, half duplex
Using eTSEC1 as destination device
Device eTSEC0 answers ...          ========> NO I WANT ETSEC1 !!!!
loopback test failed

I checked with Wireshark, the packet is correctly build. Maybe my approach is flawed ! Or maybe do you have another way to perform that kind of test ?

Thanks !

Guy Morand



More information about the U-Boot mailing list