]> git.sur5r.net Git - u-boot/commitdiff
* Add support for RMU board
authorwdenk <wdenk>
Thu, 5 Jun 2003 19:27:42 +0000 (19:27 +0000)
committerwdenk <wdenk>
Thu, 5 Jun 2003 19:27:42 +0000 (19:27 +0000)
* Add support for TQM862L at 100/50 MHz

* Patch by Pantelis Antoniou, 02 Jun 2003:
  major reconstruction of networking code;
  add "ping" support (outgoing only!)

26 files changed:
CHANGELOG
MAINTAINERS
MAKEALL
Makefile
board/rmu/Makefile [new file with mode: 0644]
board/rmu/config.mk [new file with mode: 0644]
board/rmu/flash.c [new file with mode: 0644]
board/rmu/rmu.c [new file with mode: 0644]
board/rmu/u-boot.lds [new file with mode: 0644]
board/rmu/u-boot.lds.debug [new file with mode: 0644]
board/tqm8xx/flash.c
common/cmd_net.c
common/command.c
include/cmd_confdefs.h
include/cmd_net.h
include/commproc.h
include/configs/TQM862L.h
include/configs/rmu.h [new file with mode: 0644]
include/configs/sc520_spunk.h
include/net.h
net/Makefile
net/arp.c [deleted file]
net/arp.h [deleted file]
net/bootp.c
net/net.c
net/tftp.c

index 7fba2f4406c5defea52fbc2cdd5ea86e0dd7d4a8..b613c19a801d47cdb51e258659171d047a70b651 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -11,6 +11,14 @@ Changes since U-Boot 0.3.1:
   - Changed config files of CONFIG_EEPRO100 boards to use the
     CFG_RX_ETH_BUFFER define.
 
+* Add support for RMU board
+
+* Add support for TQM862L at 100/50 MHz
+
+* Patch by Pantelis Antoniou, 02 Jun 2003:
+  major reconstruction of networking code;
+  add "ping" support (outgoing only!)
+
 * Patch by Denis Peter, 04 June 2003:
   add support for the MIP405T board
 
index 87670b4ecabbb0e1629bdc009d0724e7c10706fa..c1e5e138aa8aa514e4513f6cad572cc594edaeab 100644 (file)
@@ -63,6 +63,9 @@ Wolfgang Denk <wd@denx.de>
        IVMS8_128               MPC860
        IVMS8_256               MPC860
        LANTEC                  MPC850
+       LWMON                   MPC823
+       R360MPI                 MPC823
+       RMU                     MPC850
        RRvision                MPC823
        SM850                   MPC850
        SPD823TS                MPC823
@@ -72,6 +75,7 @@ Wolfgang Denk <wd@denx.de>
        TQM855L                 MPC855
        TQM860L                 MPC860
        TQM860L_FEC             MPC860
+       TTTech                  MPC823
        c2mon                   MPC855
        hermes                  MPC860
        lwmon                   MPC823
diff --git a/MAKEALL b/MAKEALL
index b6f636c6381f58e6a8b5c0883cd2ace41ddd5997..2edab7b1b86d400ed2c886af76f6855a1f8bf61b 100644 (file)
--- a/MAKEALL
+++ b/MAKEALL
@@ -32,11 +32,11 @@ LIST_8xx="  \
        IVMS8           IVMS8_128       IVMS8_256       KUP4K           \
        LANTEC          lwmon           MBX             MBX860T         \
        MHPC            MVS1            NETVIA          NX823           \
-       pcu_e           R360MPI         RBC823          RPXClassic      \
-       RPXlite         RRvision        SM850           SPD823TS        \
-       svm_sc8xx       SXNI855T        TOP860          TQM823L         \
-       TQM823L_LCD     TQM850L         TQM855L         TQM860L         \
-       TTTech          v37                                             \
+       pcu_e           R360MPI         RBC823          rmu             \
+       RPXClassic      RPXlite         RRvision        SM850           \
+       SPD823TS        svm_sc8xx       SXNI855T        TOP860          \
+       TQM823L         TQM823L_LCD     TQM850L         TQM855L         \
+       TQM860L         TTTech          v37                             \
 "
 
 #########################################################################
index 8ceaad1d1e43663c4c1831fa6b74a1c75fa17099..7606b0edb90168393680a924beb6ebdd2108bf24 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -323,6 +323,9 @@ RPXClassic_config:  unconfig
 RPXlite_config:                unconfig
        @./mkconfig $(@:_config=) ppc mpc8xx RPXlite
 
+rmu_config:    unconfig
+       @./mkconfig $(@:_config=) ppc mpc8xx rmu
+
 RRvision_config:       unconfig
        @./mkconfig $(@:_config=) ppc mpc8xx RRvision
 
@@ -349,10 +352,10 @@ TOP860_config:            unconfig
        @./mkconfig $(@:_config=) ppc mpc8xx top860 emk
 
 # Play some tricks for configuration selection
-# All boards can come with 50 MHz (default), 66MHz or 80MHz clock,
+# All boards can come with 50 MHz (default), 66MHz, 80MHz or 100 MHz clock,
 # but only 855 and 860 boards may come with FEC
 # and 823 boards may have LCD support
-xtract_8xx = $(subst _66MHz,,$(subst _80MHz,,$(subst _LCD,,$(subst _config,,$1))))
+xtract_8xx = $(subst _66MHz,,$(subst _80MHz,,$(subst _100MHz,,$(subst _LCD,,$(subst _config,,$1)))))
 
 FPS850L_config         \
 FPS860L_config         \
@@ -373,7 +376,8 @@ TQM860L_66MHz_config        \
 TQM860L_80MHz_config   \
 TQM862L_config         \
 TQM862L_66MHz_config   \
-TQM862L_80MHz_config:  unconfig
+TQM862L_80MHz_config   \
+TQM862L_100MHz_config: unconfig
        @ >include/config.h
        @[ -z "$(findstring _66MHz,$@)" ] || \
                { echo "#define CONFIG_66MHz"           >>include/config.h ; \
@@ -383,6 +387,10 @@ TQM862L_80MHz_config:      unconfig
                { echo "#define CONFIG_80MHz"           >>include/config.h ; \
                  echo "... with 80MHz system clock" ; \
                }
+       @[ -z "$(findstring _100MHz,$@)" ] || \
+               { echo "#define CONFIG_100MHz"          >>include/config.h ; \
+                 echo "... with 100MHz system clock" ; \
+               }
        @[ -z "$(findstring _LCD,$@)" ] || \
                { echo "#define CONFIG_LCD"             >>include/config.h ; \
                  echo "#define CONFIG_NEC_NL6648BC20"  >>include/config.h ; \
diff --git a/board/rmu/Makefile b/board/rmu/Makefile
new file mode 100644 (file)
index 0000000..ef173d0
--- /dev/null
@@ -0,0 +1,40 @@
+#
+# (C) Copyright 2000
+# 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 $(TOPDIR)/config.mk
+
+LIB    = lib$(BOARD).a
+
+OBJS   = $(BOARD).o flash.o
+
+$(LIB):        .depend $(OBJS)
+       $(AR) crv $@ $^
+
+#########################################################################
+
+.depend:       Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+               $(CC) -M $(CFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+sinclude .depend
+
+#########################################################################
diff --git a/board/rmu/config.mk b/board/rmu/config.mk
new file mode 100644 (file)
index 0000000..7cb374e
--- /dev/null
@@ -0,0 +1,28 @@
+#
+# (C) Copyright 2000
+# 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
+#
+
+#
+# RMU boards
+#
+
+TEXT_BASE = 0xfff00000
diff --git a/board/rmu/flash.c b/board/rmu/flash.c
new file mode 100644 (file)
index 0000000..c05cf32
--- /dev/null
@@ -0,0 +1,515 @@
+/*
+ * (C) Copyright 2000
+ * 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>
+#include <mpc8xx.h>
+
+flash_info_t   flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips        */
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+static void flash_get_offsets (ulong base, flash_info_t *info);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+       volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+       volatile memctl8xx_t *memctl = &immap->im_memctl;
+       unsigned long size_b0 ;
+       int i;
+
+       /* Init: no FLASHes known */
+       for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+               flash_info[i].flash_id = FLASH_UNKNOWN;
+       }
+
+       /* Static FLASH Bank configuration here - FIXME XXX */
+       size_b0 = flash_get_size((vu_long *)FLASH_BASE_PRELIM, &flash_info[0]);
+       if (flash_info[0].flash_id == FLASH_UNKNOWN) {
+               printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
+                       size_b0, size_b0<<20);
+       }
+
+       /* Remap FLASH according to real size */
+       memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & 0xFFFF8000);
+       memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
+
+       /* Re-do sizing to get full correct info */
+
+       size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
+       flash_get_offsets (CFG_FLASH_BASE, &flash_info[0]);
+
+#if CFG_MONITOR_BASE >= CFG_FLASH_BASE
+       /* monitor protection ON by default */
+       flash_protect(FLAG_PROTECT_SET,
+                     CFG_MONITOR_BASE,
+                     CFG_MONITOR_BASE+monitor_flash_len-1,
+                     &flash_info[0]);
+#endif
+
+#ifdef CFG_ENV_IS_IN_FLASH
+       /* ENV protection ON by default */
+       flash_protect(FLAG_PROTECT_SET,
+                     CFG_ENV_ADDR,
+                     CFG_ENV_ADDR+CFG_ENV_SIZE-1,
+                     &flash_info[0]);
+#endif
+
+       flash_info[0].size = size_b0;
+
+       return (size_b0);
+}
+
+/*-----------------------------------------------------------------------
+ */
+static void flash_get_offsets (ulong base, flash_info_t *info)
+{
+       int i;
+
+       /* set up sector start address table */
+       if (info->flash_id & FLASH_BTYPE) {
+               /* set sector offsets for bottom boot block type        */
+               info->start[0] = base + 0x00000000;
+               info->start[1] = base + 0x00010000;
+               info->start[2] = base + 0x00018000;
+               info->start[3] = base + 0x00020000;
+               for (i = 4; i < info->sector_count; i++) {
+                       info->start[i] = base + ((i-3) * 0x00040000) ;
+               }
+       } else {
+               /* set sector offsets for top boot block type           */
+               i = info->sector_count - 1;
+               info->start[i--] = base + info->size - 0x00010000;
+               info->start[i--] = base + info->size - 0x00018000;
+               info->start[i--] = base + info->size - 0x00020000;
+               for (; i >= 0; i--) {
+                       info->start[i] = base + i * 0x00040000;
+               }
+       }
+
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+       int i;
+
+       if (info->flash_id == FLASH_UNKNOWN) {
+               printf ("missing or unknown FLASH type\n");
+               return;
+       }
+
+       switch (info->flash_id & FLASH_VENDMASK) {
+       case FLASH_MAN_AMD:     printf ("AMD ");                break;
+       case FLASH_MAN_FUJ:     printf ("FUJITSU ");            break;
+       default:                printf ("Unknown Vendor ");     break;
+       }
+
+       switch (info->flash_id & FLASH_TYPEMASK) {
+       case FLASH_AM400B:      printf ("AM29LV400B (4 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM400T:      printf ("AM29LV400T (4 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_AM800B:      printf ("AM29LV800B (8 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM800T:      printf ("AM29LV800T (8 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_AM160B:      printf ("AM29LV160B (16 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM160T:      printf ("AM29LV160T (16 Mbit, top boot sector)\n");
+                               break;
+       case FLASH_AM320B:      printf ("AM29LV320B (32 Mbit, bottom boot sect)\n");
+                               break;
+       case FLASH_AM320T:      printf ("AM29LV320T (32 Mbit, top boot sector)\n");
+                               break;
+       default:                printf ("Unknown Chip Type\n");
+                               break;
+       }
+
+       printf ("  Size: %ld MB in %d Sectors\n",
+               info->size >> 20, info->sector_count);
+
+       printf ("  Sector Start Addresses:");
+       for (i=0; i<info->sector_count; ++i) {
+               if ((i % 5) == 0)
+                       printf ("\n   ");
+               printf (" %08lX%s",
+                       info->start[i],
+                       info->protect[i] ? " (RO)" : "     "
+               );
+       }
+       printf ("\n");
+       return;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+
+/*-----------------------------------------------------------------------
+ */
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+       short i;
+       ulong value;
+       ulong base = (ulong)addr;
+
+       /* Write auto select command: read Manufacturer ID */
+       addr[0xAAA] = 0xAAAAAAAA ;
+       addr[0x555] = 0x55555555 ;
+       addr[0xAAA] = 0x90909090 ;
+
+       value = addr[0] ;
+
+       switch (value & 0x00FF00FF) {
+       case AMD_MANUFACT:
+               info->flash_id = FLASH_MAN_AMD;
+               break;
+       case FUJ_MANUFACT:
+               info->flash_id = FLASH_MAN_FUJ;
+               break;
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               info->sector_count = 0;
+               info->size = 0;
+               return (0);                     /* no or unknown flash  */
+       }
+
+       value = addr[2] ;               /* device ID            */
+
+       switch (value & 0x00FF00FF) {
+       case (AMD_ID_LV400T & 0x00FF00FF):
+               info->flash_id += FLASH_AM400T;
+               info->sector_count = 11;
+               info->size = 0x00100000;
+               break;                          /* => 1 MB              */
+
+       case (AMD_ID_LV400B & 0x00FF00FF):
+               info->flash_id += FLASH_AM400B;
+               info->sector_count = 11;
+               info->size = 0x00100000;
+               break;                          /* => 1 MB              */
+
+       case (AMD_ID_LV800T & 0x00FF00FF):
+               info->flash_id += FLASH_AM800T;
+               info->sector_count = 19;
+               info->size = 0x00200000;
+               break;                          /* => 2 MB              */
+
+       case (AMD_ID_LV800B & 0x00FF00FF):
+               info->flash_id += FLASH_AM800B;
+               info->sector_count = 19;
+               info->size = 0x00400000;        /*%%% Size doubled by yooth */
+               break;                          /* => 4 MB              */
+
+       case (AMD_ID_LV160T & 0x00FF00FF):
+               info->flash_id += FLASH_AM160T;
+               info->sector_count = 35;
+               info->size = 0x00400000;
+               break;                          /* => 4 MB              */
+
+       case (AMD_ID_LV160B & 0x00FF00FF):
+               info->flash_id += FLASH_AM160B;
+               info->sector_count = 35;
+               info->size = 0x00800000;
+               break;                          /* => 8 MB              */
+#if 0  /* enable when device IDs are available */
+       case AMD_ID_LV320T:
+               info->flash_id += FLASH_AM320T;
+               info->sector_count = 67;
+               info->size = 0x00800000;
+               break;                          /* => 8 MB              */
+
+       case AMD_ID_LV320B:
+               info->flash_id += FLASH_AM320B;
+               info->sector_count = 67;
+               info->size = 0x01000000;
+               break;                          /* => 16 MB             */
+#endif
+       default:
+               info->flash_id = FLASH_UNKNOWN;
+               return (0);                     /* => no or unknown flash */
+
+       }
+       /*%%% sector start address modified */
+       /* set up sector start address table */
+       if (info->flash_id & FLASH_BTYPE) {
+               /* set sector offsets for bottom boot block type        */
+               info->start[0] = base + 0x00000000;
+               info->start[1] = base + 0x00010000;
+               info->start[2] = base + 0x00018000;
+               info->start[3] = base + 0x00020000;
+               for (i = 4; i < info->sector_count; i++) {
+                       info->start[i] = base + ((i-3) * 0x00040000) ;
+               }
+       } else {
+               /* set sector offsets for top boot block type           */
+               i = info->sector_count - 1;
+               info->start[i--] = base + info->size - 0x00010000;
+               info->start[i--] = base + info->size - 0x00018000;
+               info->start[i--] = base + info->size - 0x00020000;
+               for (; i >= 0; i--) {
+                       info->start[i] = base + i * 0x00040000;
+               }
+       }
+
+       /* check for protected sectors */
+       for (i = 0; i < info->sector_count; i++) {
+               /* read sector protection at sector address, (A7 .. A0) = 0x02 */
+               /* D0 = 1 if protected */
+               addr = (volatile unsigned long *)(info->start[i]);
+               info->protect[i] = addr[4] & 1 ;
+       }
+
+       /*
+        * Prevent writes to uninitialized FLASH.
+        */
+       if (info->flash_id != FLASH_UNKNOWN) {
+               addr = (volatile unsigned long *)info->start[0];
+
+               *addr = 0xF0F0F0F0;     /* reset bank */
+       }
+
+       return (info->size);
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int    flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+       vu_long *addr = (vu_long*)(info->start[0]);
+       int flag, prot, sect, l_sect;
+       ulong start, now, last;
+
+       if ((s_first < 0) || (s_first > s_last)) {
+               if (info->flash_id == FLASH_UNKNOWN) {
+                       printf ("- missing\n");
+               } else {
+                       printf ("- no sectors to erase\n");
+               }
+               return 1;
+       }
+
+       if ((info->flash_id == FLASH_UNKNOWN) ||
+           (info->flash_id > FLASH_AMD_COMP)) {
+               printf ("Can't erase unknown flash type %08lx - aborted\n",
+                       info->flash_id);
+               return 1;
+       }
+
+       prot = 0;
+       for (sect=s_first; sect<=s_last; ++sect) {
+               if (info->protect[sect]) {
+                       prot++;
+               }
+       }
+
+       if (prot) {
+               printf ("- Warning: %d protected sectors will not be erased!\n",
+                       prot);
+       } else {
+               printf ("\n");
+       }
+
+       l_sect = -1;
+
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+
+       addr[0xAAA] = 0xAAAAAAAA;
+       addr[0x555] = 0x55555555;
+       addr[0xAAA] = 0x80808080;
+       addr[0xAAA] = 0xAAAAAAAA;
+       addr[0x555] = 0x55555555;
+
+       /* Start erase on unprotected sectors */
+       for (sect = s_first; sect<=s_last; sect++) {
+               if (info->protect[sect] == 0) { /* not protected */
+                       addr = (vu_long *)(info->start[sect]) ;
+                       addr[0] = 0x30303030 ;
+                       l_sect = sect;
+               }
+       }
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       /* wait at least 80us - let's wait 1 ms */
+       udelay (1000);
+
+       /*
+        * We wait for the last triggered sector
+        */
+       if (l_sect < 0)
+               goto DONE;
+
+       start = get_timer (0);
+       last  = start;
+       addr = (vu_long *)(info->start[l_sect]);
+       while ((addr[0] & 0x80808080) != 0x80808080) {
+               if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+                       printf ("Timeout\n");
+                       return 1;
+               }
+               /* show that we're waiting */
+               if ((now - last) > 1000) {      /* every second */
+                       putc ('.');
+                       last = now;
+               }
+       }
+
+DONE:
+       /* reset to read mode */
+       addr = (vu_long *)info->start[0];
+       addr[0] = 0xF0F0F0F0;   /* reset bank */
+
+       printf (" done\n");
+       return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+       ulong cp, wp, data;
+       int i, l, rc;
+
+       wp = (addr & ~3);       /* get lower word aligned address */
+
+       /*
+        * handle unaligned start bytes
+        */
+       if ((l = addr - wp) != 0) {
+               data = 0;
+               for (i=0, cp=wp; i<l; ++i, ++cp) {
+                       data = (data << 8) | (*(uchar *)cp);
+               }
+               for (; i<4 && cnt>0; ++i) {
+                       data = (data << 8) | *src++;
+                       --cnt;
+                       ++cp;
+               }
+               for (; cnt==0 && i<4; ++i, ++cp) {
+                       data = (data << 8) | (*(uchar *)cp);
+               }
+
+               if ((rc = write_word(info, wp, data)) != 0) {
+                       return (rc);
+               }
+               wp += 4;
+       }
+
+       /*
+        * handle word aligned part
+        */
+       while (cnt >= 4) {
+               data = 0;
+               for (i=0; i<4; ++i) {
+                       data = (data << 8) | *src++;
+               }
+               if ((rc = write_word(info, wp, data)) != 0) {
+                       return (rc);
+               }
+               wp  += 4;
+               cnt -= 4;
+       }
+
+       if (cnt == 0) {
+               return (0);
+       }
+
+       /*
+        * handle unaligned tail bytes
+        */
+       data = 0;
+       for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+               data = (data << 8) | *src++;
+               --cnt;
+       }
+       for (; i<4; ++i, ++cp) {
+               data = (data << 8) | (*(uchar *)cp);
+       }
+
+       return (write_word(info, wp, data));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+       vu_long *addr = (vu_long *)(info->start[0]);
+       ulong start;
+       int flag;
+
+       /* Check if Flash is (sufficiently) erased */
+       if ((*((vu_long *)dest) & data) != data) {
+               return (2);
+       }
+       /* Disable interrupts which might cause a timeout here */
+       flag = disable_interrupts();
+
+       addr[0xAAA] = 0xAAAAAAAA;
+       addr[0x555] = 0x55555555;
+       addr[0xAAA] = 0xA0A0A0A0;
+
+       *((vu_long *)dest) = data;
+
+       /* re-enable interrupts if necessary */
+       if (flag)
+               enable_interrupts();
+
+       /* data polling for D7 */
+       start = get_timer (0);
+       while ((*((vu_long *)dest) & 0x80808080) != (data & 0x80808080)) {
+               if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+                       return (1);
+               }
+       }
+       return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
diff --git a/board/rmu/rmu.c b/board/rmu/rmu.c
new file mode 100644 (file)
index 0000000..c9925d0
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * (C) Copyright 2000
+ * 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>
+#include <mpc8xx.h>
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+
+/* ------------------------------------------------------------------------- */
+
+#define        _NOT_USED_      0xFFFFCC25
+
+const uint sdram_table[] =
+{
+       /*
+        * Single Read. (Offset 00h in UPMA RAM)
+        */
+       0x0F03CC04, 0x00ACCC24, 0x1FF74C20, _NOT_USED_,
+       _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+       /*
+        * Burst Read. (Offset 08h in UPMA RAM)
+        */
+       0x0F03CC04, 0x00ACCC24, 0x00FFCC20, 0x00FFCC20,
+       0x01FFCC20, 0x1FF74C20, _NOT_USED_, _NOT_USED_,
+       _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+       _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+       /*
+        * Single Write. (Offset 18h in UPMA RAM)
+        */
+       0x0F03CC02, 0x00AC0C24, 0x1FF74C25, _NOT_USED_,
+       _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+       /*
+        * Burst Write. (Offset 20h in UPMA RAM)
+        */
+       0x0F03CC00, 0x00AC0C20, 0x00FFFC20, 0x00FFFC22,
+       0x01FFFC24, 0x1FF74C25, _NOT_USED_, _NOT_USED_,
+       _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+       _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+       /*
+        * Refresh. (Offset 30h in UPMA RAM)
+        * (Initialization code at 0x36)
+        */
+       0x0FF0CC24, 0xFFFFCC24, _NOT_USED_, _NOT_USED_,
+       _NOT_USED_, _NOT_USED_, 0xEFFB8C34, 0x0FF74C34,
+       0x0FFACCB4, 0x0FF5CC34, 0x0FFCC34, 0x0FFFCCB4,
+
+       /*
+        * Exception. (Offset 3Ch in UPMA RAM)
+        */
+       0x0FEA8C34, 0x1FB54C34, 0xFFFFCC34, _NOT_USED_
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+       puts ("Board: RMU\n") ;
+       return (0) ;
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+    volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immap->im_memctl;
+    long int size10 ;
+
+    upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
+
+       /* Refresh clock prescalar */
+    memctl->memc_mptpr = CFG_MPTPR ;
+
+    memctl->memc_mar  = 0x00000088;
+
+       /* Map controller banks 1 to the SDRAM bank */
+    memctl->memc_or1 = CFG_OR1_PRELIM;
+    memctl->memc_br1 = CFG_BR1_PRELIM;
+
+    memctl->memc_mamr = CFG_MAMR_10COL & (~(MAMR_PTAE)); /* no refresh yet */
+
+    udelay(200);
+
+    /* perform SDRAM initializsation sequence */
+
+       memctl->memc_mcr  = 0x80002136 ; /* SDRAM bank 0 */
+    udelay(1);
+
+    memctl->memc_mamr |= MAMR_PTAE;    /* enable refresh */
+
+    udelay (1000);
+
+       /* Check Bank 0 Memory Size
+        * try 10 column mode
+        */
+
+       size10 = dram_size (CFG_MAMR_10COL, (ulong *)SDRAM_BASE_PRELIM, SDRAM_MAX_SIZE) ;
+
+    return (size10);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mamr_value, long int *base, long int maxsize)
+{
+    volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
+    volatile memctl8xx_t *memctl = &immap->im_memctl;
+    volatile long int   *addr;
+    ulong                cnt, val;
+    ulong                save[32];     /* to make test non-destructive */
+    unsigned char        i = 0;
+
+    memctl->memc_mamr = mamr_value;
+
+    for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) {
+       addr = base + cnt;      /* pointer arith! */
+
+       save[i++] = *addr;
+       *addr = ~cnt;
+    }
+
+    /* write 0 to base address */
+    addr = base;
+    save[i] = *addr;
+    *addr = 0;
+
+    /* check at base address */
+    if ((val = *addr) != 0) {
+       *addr = save[i];
+       return (0);
+    }
+
+    for (cnt = 1; cnt <= maxsize/sizeof(long); cnt <<= 1) {
+       addr = base + cnt;      /* pointer arith! */
+
+       val = *addr;
+       *addr = save[--i];
+
+       if (val != (~cnt)) {
+           return (cnt * sizeof(long));
+       }
+    }
+    return (maxsize);
+}
diff --git a/board/rmu/u-boot.lds b/board/rmu/u-boot.lds
new file mode 100644 (file)
index 0000000..c79a5a0
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * (C) Copyright 2000
+ * 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
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)          }
+  .dynsym        : { *(.dynsym)                }
+  .dynstr        : { *(.dynstr)                }
+  .rel.text      : { *(.rel.text)              }
+  .rela.text     : { *(.rela.text)     }
+  .rel.data      : { *(.rel.data)              }
+  .rela.data     : { *(.rela.data)     }
+  .rel.rodata    : { *(.rel.rodata)    }
+  .rela.rodata   : { *(.rela.rodata)   }
+  .rel.got       : { *(.rel.got)               }
+  .rela.got      : { *(.rela.got)              }
+  .rel.ctors     : { *(.rel.ctors)     }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors)     }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.bss       : { *(.rel.bss)               }
+  .rela.bss      : { *(.rela.bss)              }
+  .rel.plt       : { *(.rel.plt)               }
+  .rela.plt      : { *(.rela.plt)              }
+  .init          : { *(.init)  }
+  .plt : { *(.plt) }
+  .text      :
+  {
+    /* WARNING - the following is hand-optimized to fit within */
+    /* the sector layout of our flash chips!   XXX FIXME XXX   */
+
+    cpu/mpc8xx/start.o (.text)
+    common/dlmalloc.o  (.text)
+    lib_ppc/ppcstring.o        (.text)
+    lib_generic/vsprintf.o     (.text)
+    lib_generic/crc32.o                (.text)
+    lib_generic/zlib.o         (.text)
+/* XXX ?
+    . = env_offset;
+*/
+    common/environment.o(.text)
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x00FF) & 0xFFFFFF00;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(256);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(256);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
+
diff --git a/board/rmu/u-boot.lds.debug b/board/rmu/u-boot.lds.debug
new file mode 100644 (file)
index 0000000..22138f8
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * (C) Copyright 2000
+ * 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
+ */
+
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)          }
+  .dynsym        : { *(.dynsym)                }
+  .dynstr        : { *(.dynstr)                }
+  .rel.text      : { *(.rel.text)              }
+  .rela.text     : { *(.rela.text)     }
+  .rel.data      : { *(.rel.data)              }
+  .rela.data     : { *(.rela.data)     }
+  .rel.rodata    : { *(.rel.rodata)    }
+  .rela.rodata   : { *(.rela.rodata)   }
+  .rel.got       : { *(.rel.got)               }
+  .rela.got      : { *(.rela.got)              }
+  .rel.ctors     : { *(.rel.ctors)     }
+  .rela.ctors    : { *(.rela.ctors)    }
+  .rel.dtors     : { *(.rel.dtors)     }
+  .rela.dtors    : { *(.rela.dtors)    }
+  .rel.bss       : { *(.rel.bss)               }
+  .rela.bss      : { *(.rela.bss)              }
+  .rel.plt       : { *(.rel.plt)               }
+  .rela.plt      : { *(.rela.plt)              }
+  .init          : { *(.init)  }
+  .plt : { *(.plt) }
+  .text      :
+  {
+    /* WARNING - the following is hand-optimized to fit within */
+    /* the sector layout of our flash chips!   XXX FIXME XXX   */
+
+    cpu/mpc8xx/start.o (.text)
+    common/dlmalloc.o  (.text)
+    lib_generic/vsprintf.o     (.text)
+    lib_generic/crc32.o                (.text)
+
+    . = env_offset;
+    common/environment.o(.text)
+
+    *(.text)
+    *(.fixup)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .rodata    :
+  {
+    *(.rodata)
+    *(.rodata1)
+  }
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+
+  /* Read-write section, merged into data segment: */
+  . = (. + 0x0FFF) & 0xFFFFF000;
+  _erotext = .;
+  PROVIDE (erotext = .);
+  .reloc   :
+  {
+    *(.got)
+    _GOT2_TABLE_ = .;
+    *(.got2)
+    _FIXUP_TABLE_ = .;
+    *(.fixup)
+  }
+  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __fixup_entries = (. - _FIXUP_TABLE_)>>2;
+
+  .data    :
+  {
+    *(.data)
+    *(.data1)
+    *(.sdata)
+    *(.sdata2)
+    *(.dynamic)
+    CONSTRUCTORS
+  }
+  _edata  =  .;
+  PROVIDE (edata = .);
+
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  . = ALIGN(4096);
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(4096);
+  __init_end = .;
+
+  __bss_start = .;
+  .bss       :
+  {
+   *(.sbss) *(.scommon)
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+}
+
index 6b4ea7d227386a00059fb7019842f7bb2162fa38..98bea0e00505eb09daa9e2213bdb3f141c626402 100644 (file)
@@ -21,6 +21,8 @@
  * MA 02111-1307 USA
  */
 
+/* #define DEBUG */
+
 #include <common.h>
 #include <mpc8xx.h>
 
@@ -53,8 +55,12 @@ unsigned long flash_init (void)
 
        /* Static FLASH Bank configuration here - FIXME XXX */
 
+       debug ("\n## Get flash bank 1 size @ 0x%08x\n",FLASH_BASE0_PRELIM);
+
        size_b0 = flash_get_size((vu_long *)FLASH_BASE0_PRELIM, &flash_info[0]);
 
+       debug ("## Get flash bank 2 size @ 0x%08x\n",FLASH_BASE1_PRELIM);
+
        if (flash_info[0].flash_id == FLASH_UNKNOWN) {
                printf ("## Unknown FLASH on Bank 0 - Size = 0x%08lx = %ld MB\n",
                        size_b0, size_b0<<20);
@@ -62,6 +68,8 @@ unsigned long flash_init (void)
 
        size_b1 = flash_get_size((vu_long *)FLASH_BASE1_PRELIM, &flash_info[1]);
 
+       debug ("## Prelim. Flash bank sizes: %08lx + 0x%08lx\n",size_b0,size_b1);
+
        if (size_b1 > size_b0) {
                printf ("## ERROR: "
                        "Bank 1 (0x%08lx = %ld MB) > Bank 0 (0x%08lx = %ld MB)\n",
@@ -77,10 +85,19 @@ unsigned long flash_init (void)
                return (0);
        }
 
+       debug  ("## Before remap: "
+               "BR0: 0x%08x    OR0: 0x%08x    "
+               "BR1: 0x%08x    OR1: 0x%08x\n",
+               memctl->memc_br0, memctl->memc_or0,
+               memctl->memc_br1, memctl->memc_or1);
+
        /* Remap FLASH according to real size */
        memctl->memc_or0 = CFG_OR_TIMING_FLASH | (-size_b0 & OR_AM_MSK);
        memctl->memc_br0 = (CFG_FLASH_BASE & BR_BA_MSK) | BR_MS_GPCM | BR_V;
 
+       debug ("## BR0: 0x%08x    OR0: 0x%08x\n",
+               memctl->memc_br0, memctl->memc_or0);
+
        /* Re-do sizing to get full correct info */
        size_b0 = flash_get_size((vu_long *)CFG_FLASH_BASE, &flash_info[0]);
 
@@ -105,6 +122,9 @@ unsigned long flash_init (void)
                memctl->memc_br1 = ((CFG_FLASH_BASE + size_b0) & BR_BA_MSK) |
                                    BR_MS_GPCM | BR_V;
 
+               debug ("## BR1: 0x%08x    OR1: 0x%08x\n",
+                       memctl->memc_br1, memctl->memc_or1);
+
                /* Re-do sizing to get full correct info */
                size_b1 = flash_get_size((vu_long *)(CFG_FLASH_BASE + size_b0),
                                          &flash_info[1]);
@@ -129,8 +149,14 @@ unsigned long flash_init (void)
 
                flash_info[1].flash_id = FLASH_UNKNOWN;
                flash_info[1].sector_count = -1;
+               flash_info[1].size = 0;
+
+               debug ("## DISABLE BR1: 0x%08x    OR1: 0x%08x\n",
+                       memctl->memc_br1, memctl->memc_or1);
        }
 
+       debug ("## Final Flash bank sizes: %08lx + 0x%08lx\n",size_b0,size_b1);
+
        flash_info[0].size = size_b0;
        flash_info[1].size = size_b1;
 
@@ -215,6 +241,8 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
 
        value = addr[0];
 
+       debug ("Manuf. ID @ 0x%08lx: 0x%08lx\n", (ulong)addr, value);
+
        switch (value) {
        case AMD_MANUFACT:
                info->flash_id = FLASH_MAN_AMD;
@@ -231,6 +259,8 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
 
        value = addr[1];                        /* device ID            */
 
+       debug ("Device ID @ 0x%08lx: 0x%08lx\n", (ulong)(&addr[1]), value);
+
        switch (value) {
        case AMD_ID_LV400T:
                info->flash_id += FLASH_AM400T;
@@ -278,6 +308,12 @@ static ulong flash_get_size (vu_long *addr, flash_info_t *info)
                info->sector_count = 71;
                info->size = 0x00800000;
                break;                          /* => 8 MB              */
+       case AMD_ID_DL640:
+debug ("## oops - same ID used for AM29LV128ML/H mirror bit flash ???\n");
+               info->flash_id += FLASH_AMDL640;
+               info->sector_count = 142;
+               info->size = 0x00800000;
+               break;
        default:
                info->flash_id = FLASH_UNKNOWN;
                return (0);                     /* => no or unknown flash */
@@ -368,6 +404,8 @@ int flash_erase (flash_info_t *info, int s_first, int s_last)
        int flag, prot, sect, l_sect;
        ulong start, now, last;
 
+       debug ("flash_erase: first: %d last: %d\n", s_first, s_last);
+
        if ((s_first < 0) || (s_first > s_last)) {
                if (info->flash_id == FLASH_UNKNOWN) {
                        printf ("- missing\n");
index a1ff2ba9a6bcdc2f3fd0aec40f3594bd472740b2..e8bf0ae9f2b4b34d740a2e153eae16c1c6a3a726 100644 (file)
@@ -95,6 +95,10 @@ static void netboot_update_env(void)
        ip_to_string (NetOurDNSIP, tmp);
        setenv("dnsip", tmp);
     }
+
+    if (NetOurNISDomain[0])
+       setenv("domain", NetOurNISDomain);
+
 }
 static int
 netboot_common (int proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
@@ -165,4 +169,27 @@ netboot_common (int proto, cmd_tbl_t *cmdtp, int argc, char *argv[])
        return rcode;
 }
 
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+int do_ping (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+       if (argc < 2)
+               return -1;
+
+       NetPingIP = string_to_ip(argv[1]);
+       if (NetPingIP == 0) {
+               printf ("Usage:\n%s\n", cmdtp->usage);
+               return -1;
+       }
+
+       if (NetLoop(PING) < 0) {
+               printf("ping failed; host %s is not alive\n", argv[1]);
+               return 1;
+       }
+
+       printf("host %s is alive\n", argv[1]);
+
+       return 0;
+}
+#endif /* CFG_CMD_PING */
+
 #endif /* CFG_CMD_NET */
index 9e631f1c5dc57424c47bb8b0838a6815370d32da..d52ddf1c8f053f54aa7051eb875404ff595106f7 100644 (file)
@@ -316,6 +316,7 @@ cmd_tbl_t cmd_tbl[] = {
        CMD_TBL_NANDBOOT
        CMD_TBL_NEXT
        CMD_TBL_NM
+       CMD_TBL_PING
        CMD_TBL_PORTIO_OUT
        CMD_TBL_PCI
        CMD_TBL_PRINTENV
index 18ce6d8eef246463411bf6ccc93daa05504163e6..7ab553d317bbe25db478ec39990bcecd91ff5d9c 100644 (file)
@@ -81,6 +81,7 @@
 #define CFG_CMD_NAND   0x0000800000000000      /* NAND support                 */
 #define CFG_CMD_BMP    0x0001000000000000      /* BMP support                  */
 #define CFG_CMD_PORTIO 0x0002000000000000      /* Port I/O                     */
+#define CFG_CMD_PING   0x0004000000000000      /* ping support                 */
 
 #define CFG_CMD_ALL    0xFFFFFFFFFFFFFFFF      /* ALL commands                 */
 
                        CFG_CMD_NAND    | \
                        CFG_CMD_PCI     | \
                        CFG_CMD_PCMCIA  | \
+                       CFG_CMD_PING    | \
                        CFG_CMD_REGINFO | \
                        CFG_CMD_SAVES   | \
                        CFG_CMD_SCSI    | \
index e9ca5c5bc875fdca88268bec4af1b6c65cba9e30..842cb3e1543edcd611e2b0b302cee03e94b45054 100644 (file)
@@ -64,11 +64,24 @@ int do_dhcp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
 #define CMD_TBL_DHCP
 #endif /* CFG_CMD_DHCP */
 
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+#define        CMD_TBL_PING    MK_CMD_TBL_ENTRY(                                       \
+       "ping",         4,      2,      1,      do_ping,                        \
+       "ping    - check if host is reachable\n",                               \
+       "host\n"                                                                \
+),
+
+int do_ping (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
+#else
+#define CMD_TBL_PING
+#endif /* CFG_CMD_PING */
+
 #else
 #define CMD_TBL_BOOTP
 #define CMD_TBL_TFTPB
 #define CMD_TBL_RARPB
 #define CMD_TBL_DHCP
+#define CMD_TBL_PING
 #endif /* CFG_CMD_NET */
 
 #endif
index d6cf9baadcb13369e01eb884067679b954f2b88e..2d9ab5cdb331fb5166808211db0c4a888c1db370 100644 (file)
@@ -1254,7 +1254,11 @@ typedef struct scc_enet {
 #define PA_ENET_TXD    ((ushort)0x0008)
 #define PA_ENET_TCLK   ((ushort)0x0200)
 #define PA_ENET_RCLK   ((ushort)0x0800)
+#if defined(CONFIG_RMU)
+#define PC_ENET_TENA   ((uint)0x00000002)      /* PC14 */
+#else
 #define PB_ENET_TENA   ((uint)0x00002000)
+#endif
 #define PC_ENET_CLSN   ((ushort)0x0040)
 #define PC_ENET_RENA   ((ushort)0x0080)
 
index 653d0c79aebab4ca8d8c90e9bb13e9bf1f76120d..1d0aea1fec6584e80be858e295a81b1be9b1e2b3 100644 (file)
  * Reset PLL lock status sticky bit, timer expired status bit and timer
  * interrupt status bit
  *
- * If this is a 80 MHz CPU, set PLL multiplication factor to 5 (5*16=80)!
+ * If this is a 80 MHz or 100 MHz CPU,
+ * set PLL multiplication factor to 5 (5 * 16 = 80, 5 * 20 = 100)
  */
-#ifdef CONFIG_80MHz    /* for 80 MHz, we use a 16 MHz clock * 5 */
+#if defined(CONFIG_80MHz) || defined(CONFIG_100MHz)
 #define CFG_PLPRCR                                                     \
                ( (5-1)<<PLPRCR_MF_SHIFT | PLPRCR_TEXPS | PLPRCR_TMIST )
 #else                  /* up to 50 MHz we use a 1:1 clock */
 #define CFG_PLPRCR     (PLPRCR_SPLSS | PLPRCR_TEXPS | PLPRCR_TMIST)
-#endif /* CONFIG_80MHz */
+#endif /* CONFIG_80MHz | CONFIG_100MHz */
 
 /*-----------------------------------------------------------------------
  * SCCR - System Clock and reset Control Register              15-27
  * power management and some other internal clocks
  */
 #define SCCR_MASK      SCCR_EBDF11
-#ifdef CONFIG_80MHz    /* for 80 MHz, we use a 16 MHz clock * 5 */
+#if defined(CONFIG_80MHz) || defined(CONFIG_100MHz) /* use 16/20 MHz * 5 */
 #define CFG_SCCR       (/* SCCR_TBS  | */ \
                         SCCR_COM00   | SCCR_DFSYNC00 | SCCR_DFBRG00  | \
                         SCCR_DFNL000 | SCCR_DFNH000  | SCCR_DFLCD000 | \
                         SCCR_COM00   | SCCR_DFSYNC00 | SCCR_DFBRG00  | \
                         SCCR_DFNL000 | SCCR_DFNH000  | SCCR_DFLCD000 | \
                         SCCR_DFALCD00)
-#endif /* CONFIG_80MHz */
+#endif /* CONFIG_80MHz | CONFIG_100MHz */
 
 /*-----------------------------------------------------------------------
  * PCMCIA stuff
 /*
  * FLASH timing:
  */
-#if   defined(CONFIG_80MHz)
-/* 80 MHz CPU - 40 MHz bus: ACS = 00, TRLX = 0, CSNT = 1, SCY = 3, EHTR = 1 */
+#if defined(CONFIG_100MHz)
+/* 100 MHz CPU - 50 MHz bus:
+ * 0x...926: 9 = OR_CSNT_SAM + OR_BI; 2 = OR_SCY_2_CLK; 6 = OR_TRLX + OR_EHTR
+ * ACS = 00, TRLX = 1, CSNT = 1, SCY = 3, EHTR = 1 */
+#define CFG_OR_TIMING_FLASH    (OR_ACS_DIV1  | OR_TRLX | OR_CSNT_SAM | \
+                                OR_SCY_2_CLK | OR_EHTR | OR_BI)
+#elif defined(CONFIG_80MHz)
+/* 80 MHz CPU - 40 MHz bus:
+ * ACS = 00, TRLX = 0, CSNT = 1, SCY = 3, EHTR = 1 */
 #define CFG_OR_TIMING_FLASH    (OR_ACS_DIV1  | 0       | OR_CSNT_SAM | \
                                 OR_SCY_3_CLK | OR_EHTR | OR_BI)
 #elif defined(CONFIG_66MHz)
  * --------------------------------------------
  * Divider = 4096 * 32 * 1000 / (4 * 64) = 512000
  *
- * 50 MHz => 50.000.000 / Divider =  98
- * 66 Mhz => 66.000.000 / Divider = 129
- * 80 Mhz => 80.000.000 / Divider = 156
+ *  50 MHz =>  50.000.000 / Divider =  98
+ *  66 Mhz =>  66.000.000 / Divider = 129
+ *  80 Mhz =>  80.000.000 / Divider = 156
+ * 100 Mhz => 100.000.000 / Divider = 195
  */
-#if   defined(CONFIG_80MHz)
+#if   defined(CONFIG_100MHz)
+#define CFG_MAMR_PTA           195
+#elif defined(CONFIG_80MHz)
 #define CFG_MAMR_PTA           156
 #elif defined(CONFIG_66MHz)
 #define CFG_MAMR_PTA           129
diff --git a/include/configs/rmu.h b/include/configs/rmu.h
new file mode 100644 (file)
index 0000000..0a94714
--- /dev/null
@@ -0,0 +1,379 @@
+/*
+ * (C) Copyright 2003
+ * 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
+ */
+
+/*
+ * board/config.h - configuration options, board specific
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+
+#undef CONFIG_MPC860
+#define CONFIG_MPC850          1       /* This is a MPC850 CPU         */
+#define CONFIG_RPXLITE         1       /* RMU is the RPXlite clone */
+#define CONFIG_RMU                     1
+
+#define        CONFIG_8xx_CONS_SMC1    1       /* Console is on SMC1           */
+#undef CONFIG_8xx_CONS_SMC2
+#undef CONFIG_8xx_CONS_NONE
+#define CONFIG_BAUDRATE                9600    /* console baudrate = 9600bps   */
+#if 0
+#define CONFIG_BOOTDELAY       -1      /* autoboot disabled            */
+#else
+#define CONFIG_BOOTDELAY       5       /* autoboot after 5 seconds     */
+#endif
+
+#define        CONFIG_CLOCKS_IN_MHZ    1       /* clocks passsed to Linux in MHz */
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND                                                     \
+       "bootp; "                                                               \
+       "setenv bootargs root=/dev/nfs rw nfsroot=$(serverip):$(rootpath) "     \
+       "ip=$(ipaddr):$(serverip):$(gatewayip):$(netmask):$(hostname)::off; "   \
+       "bootm"
+
+#define CONFIG_LOADS_ECHO      1       /* echo on for serial download  */
+#undef CFG_LOADS_BAUD_CHANGE           /* don't allow baudrate change  */
+
+#undef CONFIG_WATCHDOG                 /* watchdog disabled            */
+
+#define CONFIG_BOOTP_MASK      (CONFIG_BOOTP_DEFAULT | CONFIG_BOOTP_BOOTFILESIZE)
+
+/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
+#include <cmd_confdefs.h>
+
+/*
+ * Miscellaneous configurable options
+ */
+#define        CFG_LONGHELP                    /* undef to save memory         */
+#define        CFG_PROMPT      "=> "           /* Monitor Command Prompt       */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define        CFG_CBSIZE      1024            /* Console I/O Buffer Size      */
+#else
+#define        CFG_CBSIZE      256             /* Console I/O Buffer Size      */
+#endif
+#define        CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
+#define        CFG_MAXARGS     16              /* max number of command args   */
+#define CFG_BARGSIZE   CFG_CBSIZE      /* Boot Argument Buffer Size    */
+
+#define CFG_MEMTEST_START      0x0040000       /* memtest works on     */
+#define CFG_MEMTEST_END                0x00C0000       /* 4 ... 12 MB in DRAM  */
+
+#define        CFG_LOAD_ADDR           0x100000        /* default load address */
+
+#define        CFG_HZ          1000            /* decrementer freq: 1 ms ticks */
+
+#define CFG_BAUDRATE_TABLE     { 9600, 19200, 38400, 57600, 115200 }
+
+/*
+ * Low Level Configuration Settings
+ * (address mappings, register initial values, etc.)
+ * You should know what you are doing if you make changes here.
+ */
+/*-----------------------------------------------------------------------
+ * Internal Memory Mapped Register
+ */
+#define CFG_IMMR               0xFA200000
+
+/*-----------------------------------------------------------------------
+ * Definitions for initial stack pointer and data area (in DPRAM)
+ */
+#define CFG_INIT_RAM_ADDR      CFG_IMMR
+#define        CFG_INIT_RAM_END        0x2F00  /* End of used area in DPRAM    */
+#define        CFG_GBL_DATA_SIZE       64  /* size in bytes reserved for initial data */
+#define CFG_GBL_DATA_OFFSET    (CFG_INIT_RAM_END - CFG_GBL_DATA_SIZE)
+#define        CFG_INIT_SP_OFFSET      CFG_GBL_DATA_OFFSET
+
+/*-----------------------------------------------------------------------
+ * Start addresses for the final memory configuration
+ * (Set up by the startup code)
+ * Please note that CFG_SDRAM_BASE _must_ start at 0
+ */
+#define        CFG_SDRAM_BASE          0x00000000
+#define CFG_FLASH_BASE 0xFF800000
+/*%%% #define CFG_FLASH_BASE           0xFFF00000 */
+#if defined(DEBUG) || (CONFIG_COMMANDS & CFG_CMD_IDE)
+#define        CFG_MONITOR_LEN         (256 << 10)     /* Reserve 256 kB for Monitor   */
+#else
+#define        CFG_MONITOR_LEN         (128 << 10)     /* Reserve 128 kB for Monitor   */
+#endif
+#define CFG_MONITOR_BASE       0xFFF00000
+/*%%% #define CFG_MONITOR_BASE CFG_FLASH_BASE */
+#define        CFG_MALLOC_LEN          (128 << 10)     /* Reserve 128 kB for malloc()  */
+
+/*
+ * For booting Linux, the board info and command line data
+ * have to be in the first 8 MB of memory, since this is
+ * the maximum mapped by the Linux kernel during initialization.
+ */
+#define        CFG_BOOTMAPSZ           (8 << 20)       /* Initial Memory map for Linux */
+
+/*-----------------------------------------------------------------------
+ * FLASH organization
+ */
+#define CFG_MAX_FLASH_BANKS    1       /* max number of memory banks           */
+#define CFG_MAX_FLASH_SECT     35      /* max number of sectors on one chip    */
+
+#define CFG_FLASH_ERASE_TOUT   120000  /* Timeout for Flash Erase (in ms)      */
+#define CFG_FLASH_WRITE_TOUT   500     /* Timeout for Flash Write (in ms)      */
+
+#define        CFG_ENV_IS_IN_FLASH     1
+#define        CFG_ENV_OFFSET      0x00740000  /*   Offset   of Environment Sector     */
+#define        CFG_ENV_SIZE            0x40000 /* Total Size of Environment Sector     */
+#define CFG_ENV_ADDR           (CFG_FLASH_BASE + CFG_ENV_OFFSET)
+
+/* Address and size of Redundant Environment Sector    */
+#define CFG_ENV_OFFSET_REDUND  (CFG_ENV_OFFSET+CFG_ENV_SIZE)
+#define CFG_ENV_SIZE_REDUND    (CFG_ENV_SIZE)
+
+/*-----------------------------------------------------------------------
+ * Cache Configuration
+ */
+#define CFG_CACHELINE_SIZE     16      /* For all MPC8xx CPUs                  */
+#if (CONFIG_COMMANDS & CFG_CMD_KGDB)
+#define CFG_CACHELINE_SHIFT    4       /* log base 2 of the above value        */
+#endif
+
+/*-----------------------------------------------------------------------
+ * SYPCR - System Protection Control                           11-9
+ * SYPCR can only be written once after reset!
+ *-----------------------------------------------------------------------
+ * Software & Bus Monitor Timer max, Bus Monitor enable, SW Watchdog freeze
+ */
+#if defined(CONFIG_WATCHDOG)
+#define CFG_SYPCR      (SYPCR_SWTC | SYPCR_BMT | SYPCR_BME | SYPCR_SWF | \
+                        SYPCR_SWE  | SYPCR_SWRI| SYPCR_SWP)
+#else
+#define CFG_SYPCR      (SYPCR_SWTC | 0x00000600 | SYPCR_BME | SYPCR_SWF | SYPCR_SWP)
+#endif
+
+/*-----------------------------------------------------------------------
+ * SIUMCR - SIU Module Configuration                           11-6
+ *-----------------------------------------------------------------------
+ * PCMCIA config., multi-function pin tri-state
+ */
+#define CFG_SIUMCR     (SIUMCR_MLRC10)
+
+/*-----------------------------------------------------------------------
+ * TBSCR - Time Base Status and Control                                11-26
+ *-----------------------------------------------------------------------
+ * Clear Reference Interrupt Status, Timebase freezing enabled
+ */
+#define CFG_TBSCR      (TBSCR_REFA | TBSCR_REFB | TBSCR_TBF | TBSCR_TBE)
+
+/*-----------------------------------------------------------------------
+ * RTCSC - Real-Time Clock Status and Control Register         11-27
+ *-----------------------------------------------------------------------
+ */
+/*%%%#define CFG_RTCSC (RTCSC_SEC | RTCSC_ALR | RTCSC_RTF| RTCSC_RTE) */
+#define CFG_RTCSC      (RTCSC_SEC | RTCSC_RTE)
+
+/*-----------------------------------------------------------------------
+ * PISCR - Periodic Interrupt Status and Control               11-31
+ *-----------------------------------------------------------------------
+ * Clear Periodic Interrupt Status, Interrupt Timer freezing enabled
+ */
+#define CFG_PISCR (PISCR_PS | PISCR_PITF)
+
+/*-----------------------------------------------------------------------
+ * PLPRCR - PLL, Low-Power, and Reset Control Register         15-30
+ *-----------------------------------------------------------------------
+ * Reset PLL lock status sticky bit, timer expired status bit and timer
+ * interrupt status bit
+ *
+ * If this is a 80 MHz CPU, set PLL multiplication factor to 5 (5*16=80)!
+ */
+/* up to 50 MHz we use a 1:1 clock */
+#define CFG_PLPRCR     ( (5 << PLPRCR_MF_SHIFT) | PLPRCR_TEXPS )
+
+/*-----------------------------------------------------------------------
+ * SCCR - System Clock and reset Control Register              15-27
+ *-----------------------------------------------------------------------
+ * Set clock output, timebase and RTC source and divider,
+ * power management and some other internal clocks
+ */
+#define SCCR_MASK      SCCR_EBDF00
+/* up to 50 MHz we use a 1:1 clock */
+#define CFG_SCCR       (SCCR_COM00 | SCCR_TBS)
+
+/*-----------------------------------------------------------------------
+ * PCMCIA stuff
+ *-----------------------------------------------------------------------
+ *
+ */
+#define CFG_PCMCIA_MEM_ADDR    (0xE0000000)
+#define CFG_PCMCIA_MEM_SIZE    ( 64 << 20 )
+#define CFG_PCMCIA_DMA_ADDR    (0xE4000000)
+#define CFG_PCMCIA_DMA_SIZE    ( 64 << 20 )
+#define CFG_PCMCIA_ATTRB_ADDR  (0xE8000000)
+#define CFG_PCMCIA_ATTRB_SIZE  ( 64 << 20 )
+#define CFG_PCMCIA_IO_ADDR     (0xEC000000)
+#define CFG_PCMCIA_IO_SIZE     ( 64 << 20 )
+
+/*-----------------------------------------------------------------------
+ * IDE/ATA stuff (Supports IDE harddisk on PCMCIA Adapter)
+ *-----------------------------------------------------------------------
+ */
+
+#define        CONFIG_IDE_8xx_PCCARD   1       /* Use IDE with PC Card Adapter */
+
+#undef CONFIG_IDE_8xx_DIRECT           /* Direct IDE    not supported  */
+#undef CONFIG_IDE_LED                  /* LED   for ide not supported  */
+#undef CONFIG_IDE_RESET                /* reset for ide not supported  */
+
+#define CFG_IDE_MAXBUS         1       /* max. 1 IDE bus               */
+#define CFG_IDE_MAXDEVICE      1       /* max. 1 drive per IDE bus     */
+
+#define CFG_ATA_IDE0_OFFSET    0x0000
+
+#define CFG_ATA_BASE_ADDR      CFG_PCMCIA_MEM_ADDR
+
+/* Offset for data I/O                 */
+#define CFG_ATA_DATA_OFFSET    (CFG_PCMCIA_MEM_SIZE + 0x320)
+
+/* Offset for normal register accesses */
+#define CFG_ATA_REG_OFFSET     (2 * CFG_PCMCIA_MEM_SIZE + 0x320)
+
+/* Offset for alternate registers      */
+#define CFG_ATA_ALT_OFFSET     0x0100
+
+/*-----------------------------------------------------------------------
+ *
+ *-----------------------------------------------------------------------
+ *
+ */
+/*#define      CFG_DER 0x2002000F*/
+#define CFG_DER        0
+
+/*
+ * Init Memory Controller:
+ *
+ * BR0 and OR0 (FLASH)
+ */
+
+#define FLASH_BASE_PRELIM      0xFE000000      /* FLASH base */
+#define CFG_PRELIM_OR_AM       0xFE000000      /* OR addr mask */
+
+/* FLASH timing: ACS = 0, TRLX = 0, CSNT = 0, SCY = 4, ETHR = 0, BIH = 1 */
+#define CFG_OR_TIMING_FLASH (OR_SCY_4_CLK | OR_BI)
+
+#define CFG_OR0_PRELIM (CFG_PRELIM_OR_AM | CFG_OR_TIMING_FLASH)
+#define CFG_BR0_PRELIM ((FLASH_BASE_PRELIM & BR_BA_MSK) | BR_V)
+
+/*
+ * BR1 and OR1 (SDRAM)
+ *
+ */
+#define SDRAM_BASE_PRELIM      0x00000000      /* SDRAM base   */
+#define        SDRAM_MAX_SIZE          0x01000000      /* max 16 MB */
+
+/* SDRAM timing: Multiplexed addresses, GPL5 output to GPL5_A (don't care)     */
+#define CFG_OR_TIMING_SDRAM    0x00000E00
+
+#define CFG_OR1_PRELIM (CFG_PRELIM_OR_AM | CFG_OR_TIMING_SDRAM )
+#define CFG_BR1_PRELIM ((SDRAM_BASE_PRELIM & BR_BA_MSK) | BR_MS_UPMA | BR_V )
+
+/* RPXLITE mem setting */
+#define        CFG_BR3_PRELIM  0xFA400001              /* BCSR */
+#define CFG_OR3_PRELIM 0xFFFF8910
+#define        CFG_BR4_PRELIM  0xFA000401              /* NVRAM&SRAM */
+#define CFG_OR4_PRELIM 0xFFFE0970
+
+/*
+ * Memory Periodic Timer Prescaler
+ */
+
+/* periodic timer for refresh */
+#define CFG_MAMR_PTA   20
+
+/*
+ * Refresh clock Prescalar
+ */
+#define CFG_MPTPR      MPTPR_PTP_DIV2
+
+/*
+ * MAMR settings for SDRAM
+ */
+
+/* 10 column SDRAM */
+#define CFG_MAMR_10COL ((CFG_MAMR_PTA << MAMR_PTA_SHIFT)  | MAMR_PTAE      |   \
+                        MAMR_AMA_TYPE_1 | MAMR_DSA_1_CYCL | MAMR_G0CLA_A10 |   \
+                        MAMR_RLFA_16X | MAMR_WLFA_16X | MAMR_TLFA_16X)
+
+/*
+ * Internal Definitions
+ *
+ * Boot Flags
+ */
+#define        BOOTFLAG_COLD   0x01    /* Normal Power-On: Boot from FLASH     */
+#define BOOTFLAG_WARM  0x02    /* Software reboot                      */
+
+/*
+ * BCSRx
+ *
+ * Board Status and Control Registers
+ *
+ */
+
+#define BCSR0 0xFA400000
+#define BCSR1 0xFA400001
+#define BCSR2 0xFA400002
+#define BCSR3 0xFA400003
+
+#define BCSR0_ENMONXCVR        0x01    /* Monitor XVCR Control */
+#define BCSR0_ENNVRAM  0x02    /* CS4# Control */
+#define BCSR0_LED5     0x04    /* LED5 control 0='on' 1='off' */
+#define BCSR0_LED4     0x08    /* LED4 control 0='on' 1='off' */
+#define BCSR0_FULLDPLX 0x10    /* Ethernet XCVR Control */
+#define BCSR0_COLTEST  0x20
+#define BCSR0_ETHLPBK  0x40
+#define BCSR0_ETHEN    0x80
+
+#define BCSR1_PCVCTL7  0x01    /* PC Slot B Control */
+#define BCSR1_PCVCTL6  0x02
+#define BCSR1_PCVCTL5  0x04
+#define BCSR1_PCVCTL4  0x08
+#define BCSR1_IPB5SEL  0x10
+
+#define BCSR2_ENPA5HDR 0x08    /* USB Control */
+#define BCSR2_ENUSBCLK 0x10
+#define BCSR2_USBPWREN 0x20
+#define BCSR2_USBSPD   0x40
+#define BCSR2_USBSUSP  0x80
+
+#define BCSR3_BWRTC    0x01    /* Real Time Clock Battery */
+#define BCSR3_BWNVR    0x02    /* NVRAM Battery */
+#define BCSR3_RDY_BSY  0x04    /* Flash Operation */
+#define BCSR3_RPXL     0x08    /* Reserved (reads back '1') */
+#define BCSR3_D27      0x10    /* Dip Switch settings */
+#define BCSR3_D26      0x20
+#define BCSR3_D25      0x40
+#define BCSR3_D24      0x80
+
+#endif /* __CONFIG_H */
index 2b5a54d9a02fa7c62207c65a23d811d70484023d..0a28805fda02781bd05729659d4d30634a2989af 100644 (file)
 
 #define        CFG_FIRST_PCI_IRQ   9
 #define        CFG_SECOND_PCI_IRQ  10
-#define CFG_THIRD_PCI_IRQ   11
+#define        CFG_THIRD_PCI_IRQ   11
 #define        CFG_FORTH_PCI_IRQ   12
 
 
index e4f7cbdd2245b03d2722079ae6a48ad49d14ed67..689a90f6eebaf3c822c4bbb4fed3e725fc2917cb 100644 (file)
@@ -200,7 +200,9 @@ typedef struct
 /*
  * ICMP stuff (just enough to handle (host) redirect messages)
  */
+#define ICMP_ECHO_REPLY                0       /* Echo reply                   */
 #define ICMP_REDIRECT          5       /* Redirect (change route)      */
+#define ICMP_ECHO_REQUEST      8       /* Echo request                 */
 
 /* Codes for REDIRECT. */
 #define ICMP_REDIR_NET         0       /* Redirect Net                 */
@@ -292,11 +294,15 @@ extern int                NetState;               /* Network loop state           */
 extern int             NetRestartWrap;         /* Tried all network devices    */
 #endif
 
-typedef enum { BOOTP, RARP, ARP, TFTP, DHCP } proto_t;
+typedef enum { BOOTP, RARP, ARP, TFTP, DHCP, PING, DNS } proto_t;
 
 /* from net/net.c */
 extern char    BootFile[128];                  /* Boot File name               */
 
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+extern IPaddr_t        NetPingIP;                      /* the ip address to ping               */
+#endif
+
 /* Initialize the network adapter */
 extern int     NetLoop(proto_t);
 
@@ -323,6 +329,9 @@ extern void NetSetTimeout(int, thand_f *);  /* Set timeout handler          */
 /* Transmit "NetTxPacket" */
 extern void    NetSendPacket(volatile uchar *, int);
 
+/* Transmit UDP packet, performing ARP request if needed */
+extern int     NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len);
+
 /* Processes a received packet */
 extern void    NetReceive(volatile uchar *, int);
 
@@ -373,6 +382,9 @@ static inline void NetCopyLong(ulong *to, ulong *from)
 /* Convert an IP address to a string */
 extern void    ip_to_string (IPaddr_t x, char *s);
 
+/* Convert a string to ip address */
+extern IPaddr_t string_to_ip(char *s);
+
 /* read an IP address from a environment variable */
 extern IPaddr_t getenv_IPaddr (char *);
 
index db0a69fae003748d6d54d6e16543cd8a77f1aa5b..b899d7b2f2a112c35b75525f3e860bd3e8e9a711 100644 (file)
@@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
 
 LIB    = libnet.a
 
-OBJS   = net.o tftp.o bootp.o rarp.o arp.o eth.o
+OBJS   = net.o tftp.o bootp.o rarp.o eth.o
 all:   $(LIB)
 
 $(LIB):        $(START) $(OBJS)
diff --git a/net/arp.c b/net/arp.c
deleted file mode 100644 (file)
index c09dc1a..0000000
--- a/net/arp.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * (C) Copyright 2000
- * 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>
-#include <command.h>
-#include <net.h>
-#include "bootp.h"
-#include "tftp.h"
-#include "arp.h"
-
-#if (CONFIG_COMMANDS & CFG_CMD_NET)
-
-#define TIMEOUT                5               /* Seconds before trying ARP again */
-#ifndef        CONFIG_NET_RETRY_COUNT
-# define TIMEOUT_COUNT 5               /* # of timeouts before giving up  */
-#else
-# define TIMEOUT_COUNT  (CONFIG_NET_RETRY_COUNT)
-#endif
-
-static void ArpHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len);
-static void ArpTimeout(void);
-
-int    ArpTry = 0;
-
-/*
- *     Handle a ARP received packet.
- */
-static void
-ArpHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len)
-{
-       /* Check if the frame is really an ARP reply */
-       if (memcmp (NetServerEther, NetBcastAddr, 6) != 0) {
-#ifdef DEBUG
-               printf("Got good ARP - start TFTP\n");
-#endif
-               TftpStart ();
-       }
-}
-
-
-/*
- *     Timeout on ARP request.
- */
-static void
-ArpTimeout(void)
-{
-       if (ArpTry >= TIMEOUT_COUNT) {
-               puts ("\nRetry count exceeded; starting again\n");
-               NetStartAgain ();
-       } else {
-               NetSetTimeout (TIMEOUT * CFG_HZ, ArpTimeout);
-               ArpRequest ();
-       }
-}
-
-
-void
-ArpRequest (void)
-{
-       int i;
-       volatile uchar *pkt;
-       ARP_t * arp;
-
-       printf("ARP broadcast %d\n", ++ArpTry);
-       pkt = NetTxPacket;
-
-       NetSetEther(pkt, NetBcastAddr, PROT_ARP);
-       pkt += ETHER_HDR_SIZE;
-
-       arp = (ARP_t *)pkt;
-
-       arp->ar_hrd = htons(ARP_ETHER);
-       arp->ar_pro = htons(PROT_IP);
-       arp->ar_hln = 6;
-       arp->ar_pln = 4;
-       arp->ar_op  = htons(ARPOP_REQUEST);
-
-       memcpy (&arp->ar_data[0], NetOurEther, 6);      /* source ET addr       */
-       NetWriteIP((uchar*)&arp->ar_data[6], NetOurIP); /* source IP addr       */
-       for (i=10; i<16; ++i) {
-               arp->ar_data[i] = 0;                    /* dest ET addr = 0     */
-       }
-
-       if((NetServerIP & NetOurSubnetMask) != (NetOurIP & NetOurSubnetMask)) {
-           if (NetOurGatewayIP == 0) {
-               puts ("## Warning: gatewayip needed but not set\n");
-           }
-           NetWriteIP((uchar*)&arp->ar_data[16], NetOurGatewayIP);
-       } else {
-           NetWriteIP((uchar*)&arp->ar_data[16], NetServerIP);
-       }
-
-
-       NetSendPacket(NetTxPacket, ETHER_HDR_SIZE + ARP_HDR_SIZE);
-
-       NetSetTimeout(TIMEOUT * CFG_HZ, ArpTimeout);
-       NetSetHandler(ArpHandler);
-}
-
-#endif /* CFG_CMD_NET */
diff --git a/net/arp.h b/net/arp.h
deleted file mode 100644 (file)
index b835334..0000000
--- a/net/arp.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * (C) Copyright 2000
- * 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
- */
-
-
-#ifndef __ARP_H__
-#define __ARP_H__
-
-/**********************************************************************/
-/*
- *     Global functions and variables.
- */
-
-extern int ArpTry;
-
-extern void ArpRequest (void); /* Send a ARP request */
-
-/**********************************************************************/
-
-#endif /* __ARP_H__ */
-
index 4be0ad586a6b5f3e4de75c395cadab5de677be50..8e0f332466402385ff5aedae53646195f5caa686 100644 (file)
@@ -24,7 +24,6 @@
 #include <net.h>
 #include "bootp.h"
 #include "tftp.h"
-#include "arp.h"
 #ifdef CONFIG_STATUS_LED
 #include <status_led.h>
 #endif
@@ -336,10 +335,7 @@ BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
                return;
        }
 
-       /* Send ARP request to get TFTP server ethernet address.
-        * This automagically starts TFTP, too.
-        */
-       ArpRequest();
+       TftpStart();
 }
 #endif /* !CFG_CMD_DHCP */
 
@@ -866,10 +862,7 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
                                NetState = NETLOOP_SUCCESS;
                                return;
                        }
-                       /* Send ARP request to get TFTP server ethernet address.
-                        * This automagically starts TFTP, too.
-                        */
-                       ArpRequest();
+                       TftpStart();
                        return;
                }
                break;
index b9cb67b25cefc0435fb8bfdde267196f549e1d6b..4758595d1c878a759b4c9e410632b1abb6862e77 100644 (file)
--- a/net/net.c
+++ b/net/net.c
 #include "bootp.h"
 #include "tftp.h"
 #include "rarp.h"
-#include "arp.h"
 
 #if (CONFIG_COMMANDS & CFG_CMD_NET)
 
+#define ARP_TIMEOUT            5               /* Seconds before trying ARP again */
+#ifndef        CONFIG_NET_RETRY_COUNT
+# define ARP_TIMEOUT_COUNT     5               /* # of timeouts before giving up  */
+#else
+# define ARP_TIMEOUT_COUNT  (CONFIG_NET_RETRY_COUNT)
+#endif
+
 #if 0
 #define ET_DEBUG
 #endif
@@ -88,7 +94,7 @@ ushort                NetBootFileSize=0;              /* Our bootfile size in blocks  */
 ulong          NetBootFileXferSize;    /* The actual transferred size of the bootfile (in bytes) */
 uchar          NetOurEther[6];         /* Our ethernet address                 */
 uchar          NetServerEther[6] =     /* Boot server enet address             */
-                       { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+                       { 0, 0, 0, 0, 0, 0 };
 IPaddr_t       NetOurIP;               /* Our IP addr (0 = unknown)            */
 IPaddr_t       NetServerIP;            /* Our IP addr (0 = unknown)            */
 volatile uchar *NetRxPkt;              /* Current receive packet               */
@@ -96,6 +102,8 @@ int          NetRxPktLen;            /* Current rx packet length             */
 unsigned       NetIPID;                /* IP packet ID                         */
 uchar          NetBcastAddr[6] =       /* Ethernet bcast address               */
                        { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+uchar          NetEtherNullAddr[6] =
+                       { 0, 0, 0, 0, 0, 0 };
 int            NetState;               /* Network loop state                   */
 #ifdef CONFIG_NET_MULTI
 int            NetRestartWrap = 0;     /* Tried all network devices            */
@@ -105,6 +113,12 @@ static int NetDevExists = 0;       /* At least one device configured       */
 
 char           BootFile[128];          /* Boot File name                       */
 
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+IPaddr_t       NetPingIP;              /* the ip address to ping               */
+
+static void PingStart(void);
+#endif
+
 volatile uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
 
 volatile uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets                    */
@@ -116,6 +130,81 @@ volatile uchar *NetTxPacket = 0;   /* THE transmit packet                  */
 
 static int net_check_prereq (proto_t protocol);
 
+/**********************************************************************/
+
+IPaddr_t       NetArpWaitPacketIP;
+IPaddr_t       NetArpWaitReplyIP;
+uchar         *NetArpWaitPacketMAC;    /* MAC address of waiting packet's destination  */
+uchar          *NetArpWaitTxPacket;    /* THE transmit packet                  */
+int            NetArpWaitTxPacketSize;
+uchar          NetArpWaitPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
+ulong          NetArpWaitTimerStart;
+int            NetArpWaitTry;
+
+void ArpRequest(void)
+{
+       int i;
+       volatile uchar *pkt;
+       ARP_t * arp;
+
+#ifdef ET_DEBUG
+       printf("ARP broadcast %d\n", NetArpWaitTry);
+#endif
+       pkt = NetTxPacket;
+
+       NetSetEther(pkt, NetBcastAddr, PROT_ARP);
+       pkt += ETHER_HDR_SIZE;
+
+       arp = (ARP_t *)pkt;
+
+       arp->ar_hrd = htons(ARP_ETHER);
+       arp->ar_pro = htons(PROT_IP);
+       arp->ar_hln = 6;
+       arp->ar_pln = 4;
+       arp->ar_op  = htons(ARPOP_REQUEST);
+
+       memcpy (&arp->ar_data[0], NetOurEther, 6);      /* source ET addr       */
+       NetWriteIP((uchar*)&arp->ar_data[6], NetOurIP); /* source IP addr       */
+       for (i=10; i<16; ++i) {
+               arp->ar_data[i] = 0;                    /* dest ET addr = 0     */
+       }
+
+       if((NetArpWaitPacketIP & NetOurSubnetMask) != (NetOurIP & NetOurSubnetMask)) {
+           if (NetOurGatewayIP == 0) {
+               puts ("## Warning: gatewayip needed but not set\n");
+           }
+           NetArpWaitReplyIP = NetOurGatewayIP;
+       } else
+            NetArpWaitReplyIP = NetArpWaitPacketIP;
+
+        NetWriteIP((uchar*)&arp->ar_data[16], NetArpWaitReplyIP);
+       (void) eth_send(NetTxPacket, ETHER_HDR_SIZE + ARP_HDR_SIZE);
+}
+
+void ArpTimeoutCheck(void)
+{
+       ulong t;
+
+       if (!NetArpWaitPacketIP)
+               return;
+
+       t = get_timer(0);
+
+       /* check for arp timeout */
+       if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT * CFG_HZ) {
+               NetArpWaitTry++;
+
+               if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) {
+                       puts ("\nARP Retry count exceeded; starting again\n");
+                       NetArpWaitTry = 0;
+                       NetStartAgain();
+               } else {
+                       NetArpWaitTimerStart = t;
+                       ArpRequest();
+               }
+       }
+}
+
 /**********************************************************************/
 /*
  *     Main network processing loop.
@@ -133,6 +222,14 @@ NetLoop(proto_t protocol)
        NetDevExists = 0;
 #endif
 
+       /* XXX problem with bss workaround */
+       NetArpWaitPacketMAC = NULL;
+       NetArpWaitTxPacket = NULL;
+       NetArpWaitPacketIP = 0;
+       NetArpWaitReplyIP = 0;
+       NetArpWaitTxPacket = NULL;
+       NetTxPacket = NULL;
+
        if (!NetTxPacket) {
                int     i;
 
@@ -144,6 +241,13 @@ NetLoop(proto_t protocol)
                for (i = 0; i < PKTBUFSRX; i++) {
                        NetRxPackets[i] = NetTxPacket + (i+1)*PKTSIZE_ALIGN;
                }
+
+       }
+
+       if (!NetArpWaitTxPacket) {
+               NetArpWaitTxPacket = &NetArpWaitPacketBuf[0] + (PKTALIGN - 1);
+               NetArpWaitTxPacket -= (ulong)NetArpWaitTxPacket % PKTALIGN;
+               NetArpWaitTxPacketSize = 0;
        }
 
        eth_halt();
@@ -165,11 +269,27 @@ restart:
         */
 
        switch (protocol) {
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+       case PING:
+#endif
        case TFTP:
                NetCopyIP(&NetOurIP, &bd->bi_ip_addr);
-               NetServerIP     = getenv_IPaddr ("serverip");
                NetOurGatewayIP = getenv_IPaddr ("gatewayip");
                NetOurSubnetMask= getenv_IPaddr ("netmask");
+
+               switch (protocol) {
+               case TFTP:
+                       NetServerIP = getenv_IPaddr ("serverip");
+                       break;
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+               case PING:
+                       /* nothing */
+                       break;
+#endif
+               default:
+                       break;
+               }
+
                break;
        case BOOTP:
        case RARP:
@@ -202,8 +322,7 @@ restart:
                switch (protocol) {
                case TFTP:
                        /* always use ARP to get server ethernet address */
-                       ArpTry = 0;
-                       ArpRequest ();
+                       TftpStart();
                        break;
 
 #if (CONFIG_COMMANDS & CFG_CMD_DHCP)
@@ -224,6 +343,11 @@ restart:
                        RarpTry = 0;
                        RarpRequest ();
                        break;
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+               case PING:
+                       PingStart();
+                       break;
+#endif
                default:
                        break;
                }
@@ -260,6 +384,7 @@ restart:
                        return (-1);
                }
 
+               ArpTimeoutCheck();
 
                /*
                 *      Check for a timeout, and run the timeout handler
@@ -376,7 +501,138 @@ NetSendPacket(volatile uchar * pkt, int len)
        (void) eth_send(pkt, len);
 }
 
+int
+NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport, int len)
+{
+       /* convert to new style broadcast */
+       if (dest == 0)
+               dest = 0xFFFFFFFF;
+
+       /* if broadcast, make the ether address a broadcast and don't do ARP */
+       if (dest == 0xFFFFFFFF)
+               ether = NetBcastAddr;
+
+       /* if MAC address was not discovered yet, save the packet and do an ARP request */
+       if (memcmp(ether, NetEtherNullAddr, 6) == 0) {
+
+#ifdef ET_DEBUG
+               printf("sending ARP for %08lx\n", dest);
+#endif
+
+               NetArpWaitPacketIP = dest;
+               NetArpWaitPacketMAC = ether;
+               NetSetEther (NetArpWaitTxPacket, NetArpWaitPacketMAC, PROT_IP);
+               NetSetIP (NetArpWaitTxPacket + ETHER_HDR_SIZE, dest, dport, sport, len);
+               memcpy(NetArpWaitTxPacket + ETHER_HDR_SIZE + IP_HDR_SIZE,
+                       (uchar *)NetTxPacket + ETHER_HDR_SIZE + IP_HDR_SIZE, len);
+
+               /* size of the waiting packet */
+               NetArpWaitTxPacketSize = ETHER_HDR_SIZE + IP_HDR_SIZE + len;
+
+               /* and do the ARP request */
+               NetArpWaitTry = 1;
+               NetArpWaitTimerStart = get_timer(0);
+               ArpRequest();
+               return 1;       /* waiting */
+       }
+
+#ifdef ET_DEBUG
+       printf("sending UDP to %08lx/%02x:%02x:%02x:%02x:%02x:%02x\n",
+                       dest, ether[0], ether[1], ether[2], ether[3], ether[4], ether[5]);
+#endif
+
+       NetSetEther (NetTxPacket, ether, PROT_IP);
+       NetSetIP (NetTxPacket + ETHER_HDR_SIZE, dest, dport, sport, len);
+       (void) eth_send(NetTxPacket, ETHER_HDR_SIZE + IP_HDR_SIZE + len);
+
+       return 0;       /* transmited */
+}
+
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+static ushort PingSeqNo;
+
+int PingSend(void)
+{
+       static uchar mac[6];
+       volatile IP_t *ip;
+       volatile ushort *s;
+
+       /* XXX always send arp request */
+
+       memcpy(mac, NetEtherNullAddr, 6);
+
+#ifdef ET_DEBUG
+       printf("sending ARP for %08lx\n", NetPingIP);
+#endif
+
+       NetArpWaitPacketIP = NetPingIP;
+       NetArpWaitPacketMAC = mac;
+
+       NetSetEther(NetArpWaitTxPacket, mac, PROT_IP);
+
+       ip = (volatile IP_t *)(NetArpWaitTxPacket + ETHER_HDR_SIZE);
+
+       /*
+        *      Construct an IP and ICMP header.  (need to set no fragment bit - XXX)
+        */
+       ip->ip_hl_v  = 0x45;            /* IP_HDR_SIZE / 4 (not including UDP) */
+       ip->ip_tos   = 0;
+       ip->ip_len   = htons(IP_HDR_SIZE_NO_UDP + 8);
+       ip->ip_id    = htons(NetIPID++);
+       ip->ip_off   = htons(0x4000);   /* No fragmentation */
+       ip->ip_ttl   = 255;
+       ip->ip_p     = 0x01;            /* ICMP */
+       ip->ip_sum   = 0;
+       NetCopyIP((void*)&ip->ip_src, &NetOurIP); /* already in network byte order */
+       NetCopyIP((void*)&ip->ip_dst, &NetPingIP);         /* - "" - */
+       ip->ip_sum   = ~NetCksum((uchar *)ip, IP_HDR_SIZE_NO_UDP / 2);
+
+       s = &ip->udp_src;               /* XXX ICMP starts here */
+       s[0] = htons(0x0800);           /* echo-request, code */
+       s[1] = 0;                       /* checksum */
+       s[2] = 0;                       /* identifier */
+       s[3] = htons(PingSeqNo++);      /* sequence number */
+       s[1] = ~NetCksum((uchar *)s, 8/2);
+
+       /* size of the waiting packet */
+       NetArpWaitTxPacketSize = ETHER_HDR_SIZE + IP_HDR_SIZE_NO_UDP + 8;
+
+       /* and do the ARP request */
+       NetArpWaitTry = 1;
+       NetArpWaitTimerStart = get_timer(0);
+       ArpRequest();
+       return 1;       /* waiting */
+}
+
+static void
+PingTimeout (void)
+{
+       eth_halt();
+       NetState = NETLOOP_FAIL;        /* we did not get the reply */
+}
 
+static void
+PingHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
+{
+       IPaddr_t tmp;
+       volatile IP_t *ip = (volatile IP_t *)pkt;
+
+       tmp = NetReadIP((void *)&ip->ip_src);
+       if (tmp != NetPingIP)
+               return;
+
+       NetState = NETLOOP_SUCCESS;
+}
+
+static void PingStart(void)
+{
+       NetSetTimeout (10 * CFG_HZ, PingTimeout);
+       NetSetHandler (PingHandler);
+
+       PingSend();
+}
+
+#endif
 
 void
 NetReceive(volatile uchar * pkt, int len)
@@ -387,7 +643,6 @@ NetReceive(volatile uchar * pkt, int len)
        IPaddr_t tmp;
        int     x;
 
-
        NetRxPkt = pkt;
        NetRxPktLen = len;
        et = (Ethernet_t *)pkt;
@@ -462,14 +717,40 @@ NetReceive(volatile uchar * pkt, int len)
                        NetCopyIP(&arp->ar_data[16], &arp->ar_data[6]);
                        memcpy   (&arp->ar_data[ 0], NetOurEther, 6);
                        NetCopyIP(&arp->ar_data[ 6], &NetOurIP);
-                       NetSendPacket((uchar *)et,((uchar *)arp-pkt)+ARP_HDR_SIZE);
+                       (void) eth_send((uchar *)et, ((uchar *)arp-pkt) + ARP_HDR_SIZE);
                        return;
-               case ARPOP_REPLY:               /* set TFTP server eth addr     */
+
+               case ARPOP_REPLY:               /* arp reply */
+                       /* are we waiting for a reply */
+                       if (!NetArpWaitPacketIP || !NetArpWaitPacketMAC)
+                               break;
 #ifdef ET_DEBUG
-                       printf("Got ARP REPLY, set server/gtwy eth addr\n");
+                       printf("Got ARP REPLY, set server/gtwy eth addr (%02x:%02x:%02x:%02x:%02x:%02x)\n",
+                               arp->ar_data[0], arp->ar_data[1],
+                               arp->ar_data[2], arp->ar_data[3],
+                               arp->ar_data[4], arp->ar_data[5]);
 #endif
-                       memcpy (NetServerEther, &arp->ar_data[0], 6);
-                       (*packetHandler)(0,0,0,0);      /* start TFTP */
+
+                       tmp = NetReadIP(&arp->ar_data[6]);
+
+                       /* matched waiting packet's address */
+                       if (tmp == NetArpWaitReplyIP) {
+#ifdef ET_DEBUG
+                               printf("Got it\n");
+#endif
+                               /* save address for later use */
+                               memcpy(NetArpWaitPacketMAC, &arp->ar_data[0], 6);
+
+                               /* modify header, and transmit it */
+                               memcpy(((Ethernet_t *)NetArpWaitTxPacket)->et_dest, NetArpWaitPacketMAC, 6);
+                               (void) eth_send(NetArpWaitTxPacket, NetArpWaitTxPacketSize);
+
+                               /* no arp request pending now */
+                               NetArpWaitPacketIP = 0;
+                               NetArpWaitTxPacketSize = 0;
+                               NetArpWaitPacketMAC = NULL;
+
+                       }
                        return;
                default:
 #ifdef ET_DEBUG
@@ -553,13 +834,26 @@ NetReceive(volatile uchar * pkt, int len)
                if (ip->ip_p == IPPROTO_ICMP) {
                        ICMP_t *icmph = (ICMP_t *)&(ip->udp_src);
 
-                       if (icmph->type != ICMP_REDIRECT)
-                               return;
+                       switch (icmph->type) {
+                       case ICMP_REDIRECT:
                        if (icmph->code != ICMP_REDIR_HOST)
                                return;
                        puts (" ICMP Host Redirect to ");
                        print_IPaddr(icmph->un.gateway);
                        putc(' ');
+                               break;
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+                       case ICMP_ECHO_REPLY:
+                               /*
+                                *      IP header OK.  Pass the packet to the current handler.
+                                */
+                               /* XXX point to ip packet */
+                               (*packetHandler)((uchar *)ip, 0, 0, 0);
+                               break;
+#endif
+                       default:
+                               return;
+                       }
                } else if (ip->ip_p != IPPROTO_UDP) {   /* Only UDP packets */
                        return;
                }
@@ -582,15 +876,25 @@ NetReceive(volatile uchar * pkt, int len)
 static int net_check_prereq (proto_t protocol)
 {
        switch (protocol) {
-       case ARP:       /* nothing to do */
-                       break;
-
+                       /* Fall through */
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+       case PING:
+                       if (NetPingIP == 0) {
+                               puts ("*** ERROR: ping address not given\n");
+                               return (1);
+                       }
+                       goto common;
+#endif
        case TFTP:
                        if (NetServerIP == 0) {
                                puts ("*** ERROR: `serverip' not set\n");
                                return (1);
                        }
 
+#if (CONFIG_COMMANDS & CFG_CMD_PING)
+               common:
+#endif
+
                        if (NetOurIP == 0) {
                                puts ("*** ERROR: `ipaddr' not set\n");
                                return (1);
@@ -626,6 +930,8 @@ static int net_check_prereq (proto_t protocol)
 #endif
                        }
                        /* Fall through */
+               default:
+                       return(0);
        }
        return (0);     /* OK */
 }
@@ -723,22 +1029,14 @@ void ip_to_string (IPaddr_t x, char *s)
     );
 }
 
-void print_IPaddr (IPaddr_t x)
-{
-    char tmp[16];
-
-    ip_to_string(x, tmp);
-
-    puts(tmp);
-}
-
-IPaddr_t getenv_IPaddr (char *var)
+IPaddr_t string_to_ip(char *s)
 {
        IPaddr_t addr;
-       char *s, *e;
+       char *e;
        int i;
 
-       s = getenv (var);
+       if (s == NULL)
+               return(0);
 
        for (addr=0, i=0; i<4; ++i) {
                ulong val = s ? simple_strtoul(s, &e, 10) : 0;
@@ -751,3 +1049,17 @@ IPaddr_t getenv_IPaddr (char *var)
 
        return (htonl(addr));
 }
+
+void print_IPaddr (IPaddr_t x)
+{
+    char tmp[16];
+
+    ip_to_string(x, tmp);
+
+    puts(tmp);
+}
+
+IPaddr_t getenv_IPaddr (char *var)
+{
+       return (string_to_ip(getenv(var)));
+}
index 0ad244fd97bc27daa281c0320fa6d72ff60f31b2..5598be32f130550de43a2fb2fd1298deb7103d82 100644 (file)
@@ -142,10 +142,7 @@ TftpSend (void)
                break;
        }
 
-       NetSetEther (NetTxPacket, NetServerEther, PROT_IP);
-       NetSetIP (NetTxPacket + ETHER_HDR_SIZE, NetServerIP,
-                                       TftpServerPort, TftpOurPort, len);
-       NetSendPacket (NetTxPacket, ETHER_HDR_SIZE + IP_HDR_SIZE + len);
+       NetSendUDPPacket(NetServerEther, NetServerIP, TftpServerPort, TftpOurPort, len);
 }
 
 
@@ -257,17 +254,6 @@ TftpTimeout (void)
 void
 TftpStart (void)
 {
-#ifdef ET_DEBUG
-       printf ("\nServer ethernet address %02x:%02x:%02x:%02x:%02x:%02x\n",
-               NetServerEther[0],
-               NetServerEther[1],
-               NetServerEther[2],
-               NetServerEther[3],
-               NetServerEther[4],
-               NetServerEther[5]
-       );
-#endif /* DEBUG */
-
        if (BootFile[0] == '\0') {
                IPaddr_t OurIP = ntohl(NetOurIP);
 
@@ -320,6 +306,9 @@ TftpStart (void)
        TftpState = STATE_RRQ;
        TftpOurPort = 1024 + (get_timer(0) % 3072);
 
+       /* zero out server ether in case the server ip has changed */
+       memset(NetServerEther, 0, 6);
+
        TftpSend ();
 }