[ixp1200] Addendum to Microcode problems...

Austen McDonald austen at cc.gatech.edu
Tue Jun 19 12:12:01 EDT 2001


	I forgot to mention: Im running linux and here is the code that
initializes the giga macs:

/* mac.c
 * Change the CSRs inside the of one of the StrongARM's MACs
 *
 * Austen McDonald
 * austen at cc.gatech.edu
 * May 2001
 */

#include <asm/arch-ixp1200/hardware.h>
#include <asm/arch-ixp1200/ixp1200eb.h>
#include <stdio.h>
#include <string.h>

#define VERSION "v1.2.6"

void printHelp() {
   printf("mac %s, initializes IXP MACs 0 (10/100) and 1 (gigabit)\n",VERSION);
   printf("Austen McDonald <austen at cc.gatech.edu>, Georgia Tech\n\n");
   printf("Usage: mac [--help] [--status] [--set mac port addr]\n");
   printf("  (no args)   intializes and resets both macs (clears hw addrs and counters)\n");
   printf("  --status    prints the RCV_RDY_LO and _HI registers, hardware addresses,\n");
   printf("              and counters. No reset.\n");
   printf("  --set       sets hardware address for /mac/ /port/ to /addr/, where /addr/\n");
   printf("              is a 12 character string of hex digits. No reset.\n");
}

void printStatus(volatile unsigned int* mac0, volatile unsigned int* mac1) {
   int i,j;
   unsigned char addr;
   unsigned int x;

   printf("RCV_RDY_LO: 0x%.8x\n",
     *(volatile unsigned long*)(MICROENGINE_FBI_BASE+0x400C4));
   printf("RCV_RDY_HI: 0x%.8x\n",
     *(volatile unsigned long*)(MICROENGINE_FBI_BASE+0x400C8));
   printf("RCV_RDY_CNT: 0x%.8x\n",
     *(volatile unsigned long*)(MICROENGINE_FBI_BASE+0x400C0));
   printf("XMIT_RDY_CTL: 0x%.8x\n",
     *(volatile unsigned long*)(MICROENGINE_FBI_BASE+0x400FC));
   printf("XMIT_PTR: 0x%.8x\n",
     *(volatile unsigned long*)(MICROENGINE_FBI_BASE+0x400E0));
   printf("MAC 0 (IXF440, 10/100Mbps) HW Addresses:\n");
   for(i=0;i<8;i++) { /* eight ports */
      printf("  port %i: ",i);
      for(j=0;j<6;j++) {
         addr = *(mac0+i*0x400+0x28+j);
         printf("%.2x",addr);
         if(j != 5)
            printf(":");
      }
      i++;
      printf("  port %i: ",i);
      for(j=0;j<6;j++) {
         addr = *(mac0+i*0x400+0x28+j);
         printf("%.2x",addr);
         if(j != 5)
            printf(":");
      }
      printf("\n");
   }
   printf("MAC 1 (IXF1002, Gigabit) HW Addresses:\n");
   printf("  port 0: ");
   for(j=0;j<6;j++) {
      addr = *(mac1+0x30+j);
      printf("%.2x",addr);
      if(j != 5)
         printf(":");
   }
   printf("  port 1: ");
   for(j=0;j<6;j++) {
      addr = *(mac1+0x400+0x30+j);
      printf("%.2x",addr);
      if(j != 5)
         printf(":");
   }
   printf("\n");

   /* now for the net statistics */
   printf("MAC 0 (IXF440, 10/100Mbps) Status:\n");
   for(i=0;i<8;i++) { /* 8 ports */
      printf("  port %i: ",i);
      printf("RX Count: 0x");
      x = *(mac0+i*0x400+0x200+0x90);
      x |= *(mac0+i*0x400+0x200+0x90+1) << 8;
      x |= *(mac0+i*0x400+0x200+0x90+2) << 16;
      x |= *(mac0+i*0x400+0x200+0x90+3) << 24;
      printf("%.8x",x);
      printf(" TX Count: 0x");
      x = *(mac0+i*0x400+0x200);
      x |= *(mac0+i*0x400+0x200+1) << 8;
      x |= *(mac0+i*0x400+0x200+2) << 16;
      x |= *(mac0+i*0x400+0x200+3) << 24;
      printf("%.8x",x);
      printf("\n");
   }
   printf("MAC 1 (IXF1002, Gigabit) Status:\n");
   for(i=0;i<2;i++) { /* 2 ports */
      printf("  port %i: ",i);
      printf("RX Count: 0x");
      x = *(mac1+i*0x400+0x200+0x90);
      x |= *(mac1+i*0x400+0x200+0x90+1) << 8;
      x |= *(mac1+i*0x400+0x200+0x90+2) << 16;
      x |= *(mac1+i*0x400+0x200+0x90+3) << 24;
      printf("%.8x",x);
      printf(" TX Count: 0x");
      x = *(mac1+i*0x400+0x200);
      x |= *(mac1+i*0x400+0x200+1) << 8;
      x |= *(mac1+i*0x400+0x200+2) << 16;
      x |= *(mac1+i*0x400+0x200+3) << 24;
      printf("%.8x",x);
      printf("\n          GMII_STT: 0x%.2x%.2x GMII_EXT_STT: 0x%.2x%.2x GPCS_STT: 0x%.2x%.2x",
        *(mac1+i*0x400+0x53),*(mac1+i*0x400+0x52),
        *(mac1+i*0x400+0x6f),*(mac1+i*0x400+0x6e),
        *(mac1+i*0x400+0x71),*(mac1+i*0x400+0x70));
      printf("\n          AN_PRT_ABL: 0x%.2x%.2x",
        *(mac1+i*0x400+0x5b),*(mac1+i*0x400+0x5a));
      printf("\n");
   }
}

int main(int argc, char** argv) {
   volatile unsigned int* mac0 = (volatile unsigned int*)(SRAM_SLOW_PORT_BASE);
   volatile unsigned int* mac1 = (volatile unsigned int*)(SRAM_SLOW_PORT_BASE+0x8000);
   int i,j;
   int mac;
   int port;
   int hi;
   short low;
   char byte[] = "0x00";

   if(argc == 2) {
      if(!strcmp(argv[1],"--status"))
         printStatus(mac0,mac1);
      else
         printHelp();
      exit(0);
   }
   for(i=1;i<argc;) {
      if(!strcmp(argv[i],"--set")) {
         i++;
         if(argc-i < 3) {
            printf("Missing arguments to --set\n");
            printHelp();
            exit(-1);
         }
         mac = atoi(argv[i]);
         if(mac != 0 && mac != 1) {
            printf("Valid MAC numbers are 0 and 1\n");
            printHelp();
            exit(-1);
         }
         i++;  
         port = atoi(argv[i]);
         if((mac == 0 && (port < 0 || port > 7)) || 
            (mac == 1 && (port < 0 || port > 1))) {
            printf("Invalid port number for selected MAC\n");
            printHelp();
            exit(-1);
         }
         i++;
         if(strlen(argv[i]) != 12) {
            printf("Invalid address\n");
            printHelp();
            exit(-1);
         }
         for(j=0;j<12;j+=2) {
            strncpy(byte+2,&(argv[i][j]),2);
            if(mac == 0)
               *(mac0+0x400*port+0x28+j/2) = strtol(byte,NULL,16);
            else
               *(mac1+0x400*port+0x30+j/2) = strtol(byte,NULL,16);
         }
         i++;
      } else {
         printHelp();
         exit(-1);
      }
      printStatus(mac0,mac1);
      exit(0);
   }
   
   printf("Initializing MAC 0 (IXF440 10/100Mbps)...");
   /* reset all registers in MAC 0 */
   
   /* docs (iXF440 datasheet) outline the following process for init:
    *  1. reset port: write 6 to PORT_CTR, then write 1 to PORT_CTR
    *  2. init port's regs
    *  3. write 18 to PORT_CTR
    */
   for(i=0;i<8;i++) { /* eight ports */
      /* 1. */
      *(mac0+i*0x400+0x5) = 0x06; /* PORT_CTR */ /* control reset, port reset */
      *(mac0+i*0x400+0x5) = 0x0;
      *(mac0+i*0x400+0x5) = 0x01; /* reset counters */
      /* wait 100cyc for counter reset */
      for(j=0;j<100;j++)
         j = j + j*0; /* fake the compiler out; otherwise, it will optimize */
                      /* out this loop. */
   
      /* 2. */
      /* IX Bus Config: FFO_BUS: big endian, 64bit bus */
      *(mac0+i*0x400+0x12) = 0x03;
   
      /* 3. */
      *(mac0+i*0x400+0x5) = 0x20; /* PORT_CTR: transmit restart */
      *(mac0+i*0x400+0x5) = 0x18; /* PORT_CTR: tx enable, rx enable */
   }
   printf("intialized\n");

   printf("Initializing MAC 1 (IXF1002 Gigabit)...");

   /* docs (IXF1002 datasheet) outline the following process for init:
    *  1. reset port: write 7 to PORT_CTR, then write 0 to PORT_CTR
    *  2. init port's regs
    *  3. write 18 to PORT_CTR
    */
   for(i=0;i<2;i++) { /* two ports */
      /* 1. */
      *(mac1+i*0x400+0x4) = 0x07; /* PORT_CTR */
      *(mac1+i*0x400+0x4) = 0x00; /* PORT_CTR */
   
      /* 2. */
      /* PORT_MODE: GPCS mode on, 64bit bus, no packet status, big endian */
      *(mac1+i*0x400+0x24) = 0x0b01; 
      /* TX_RX_PARAM: drop CRC */
//    *(mac1+i*0x400+0x27) = 0x08; /* uh, should we do this? */

      /* GMII Control Register: reset GPCS, GMII logic */
      *(mac1+i*0x400+0x50) = 8000;
      for(j=0;j<100;j++)
         j = j + j*0; /* fake the compiler out; otherwise, it will optimize */
                      /* out this loop. */
      /* GMII Control Register: autoneg, restart autoneg */
      *(mac1+i*0x400+0x50) = 0x1340;
      //*(mac1+i*0x400+0x50) = 0x0140;

      /* 3. */
      *(mac1+i*0x400+4) = 0x18; /* PORT_CTR */
   }
   printf("intialized\n");

   return 0;
}




More information about the ixp1200 mailing list