]> www.infradead.org Git - users/rw/ppcboot.git/commitdiff
Merging ARMBoot patches per Sep 23 22:12 MEST:
authorwdenk <wdenk>
Tue, 24 Sep 2002 10:47:11 +0000 (10:47 +0000)
committerwdenk <wdenk>
Tue, 24 Sep 2002 10:47:11 +0000 (10:47 +0000)
- network patch by Robert Kaiser:
  o need to handle byte order for Netmask, Gateway IP, etc.
- fixes in 3c589 driver:
  o set correct MAC address
  o add delay to make sure board is ready to transmit
  o TX data must be padded to *double* words (4 bytes)

16 files changed:
CHANGELOG
board/smdk2410/config.mk
board/trab/trab.c
cpu/arm920t/cpu.c
cpu/arm920t/interrupts.c
cpu/arm920t/serial.c
cpu/arm920t/start.S
cpu/mpc8xx/lcd.c
drivers/3c589.c
drivers/smc91111.c
drivers/smc91111.h
include/net.h
net/arp.c
net/bootp.c
net/net.c
net/tftp.c

index 3dc5c811d7d9218e72011bef7176f7ec7a96d169..04e7542c34e897ea12ef0b8b44df4371deacd9ef 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,16 @@ Modifications for 1.2.0:
 
 For details about the current modifications, please see README-WIP
 
+* Merging ARMBoot patches per Sep 23 22:12 MEST:
+  - network patch by Robert Kaiser:
+    o need to handle byte order for Netmask, Gateway IP, etc.
+  - fixes in 3c589 driver:
+    o set correct MAC address
+    o add delay to make sure board is ready to transmit
+    o TX data must be padded to *double* words (4 bytes)
+
+* Patches by Gary Jennejohn, 22 Sep 2002:
+  - fix problems, enable I-cache
 
 * Patch by Stefan Röse, 20 Sep 2002:
   - CPCI4052: new FPGA image included, jffs2 support added.
index e61bea0e4296b83c3b2583ca070d258dc3d5db55..b06b493c79e8085cfacc7507d3914cb008d952c6 100644 (file)
@@ -18,7 +18,7 @@
 #
 # we load ourself to 33F0'0000
 #
-# download areas is 3300'0000
+# download area is 3300'0000
 #
 
 
index 8e0a006960d3c6fb81b55fc5b68d08480a85add6..1b3fc90dd492e7d87a316e80ee2b389a4e5c3c3e 100644 (file)
@@ -75,7 +75,7 @@ int board_init ()
        /* adress of boot parameters */
        gd->bd->bi_boot_params = 0x0c000100;
 
-       return 1;
+       return 0;
 }
 
 int dram_init (void)
@@ -84,5 +84,5 @@ int dram_init (void)
 
        gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
        gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
-       return PHYS_SDRAM_1_SIZE;
+       return 0;
 }
index 73c32cea77db966333ceffb90c676fd48233bcc2..41cebdfd94b3710557680ab8faf67c9437b95576 100644 (file)
@@ -33,8 +33,6 @@
 #include <command.h>
 #include <arm920t.h>
 
-/* it makes no sense to use the caches if the MMU also isn't used */
-#ifdef USE_920T_MMU
 /* read co-processor 15, register #1 (control register) */
 static unsigned long read_p15_c1 (void)
 {
@@ -85,7 +83,6 @@ static void cp_delay (void)
 #define C1_IC          (1<<12)         /* icache off/on */
 #define C1_HIGH_VECTORS        (1<<13) /* location of vectors: low/high addresses */
 #define RESERVED_1     (0xf << 3)      /* must be 111b for R/W */
-#endif /* USE_920T_MMU */
 
 int cpu_init (void)
 {
@@ -112,13 +109,10 @@ int cleanup_before_linux (void)
         * we turn off caches etc ...
         */
 
-#ifdef USE_920T_MMU
        unsigned long i;
-#endif
 
        disable_interrupts ();
 
-#ifdef USE_920T_MMU
        /* turn off I/D-cache */
        asm ("mrc p15, 0, %0, c1, c0, 0":"=r" (i));
        i &= ~(C1_DC | C1_IC);
@@ -127,7 +121,6 @@ int cleanup_before_linux (void)
        /* flush I/D-cache */
        i = 0;
        asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));
-#endif
        return (0);
 }
 
@@ -141,7 +134,6 @@ int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
        return (0);
 }
 
-#ifdef USE_920T_MMU
 void icache_enable (void)
 {
        ulong reg;
@@ -165,6 +157,8 @@ int icache_status (void)
        return (read_p15_c1 () & C1_IC) != 0;
 }
 
+#ifdef USE_920T_MMU
+/* It makes no sense to use the dcache if the MMU is not enabled */
 void dcache_enable (void)
 {
        ulong reg;
index 9bbac5c10b192572fb8de40cd3c48c64e27dda73..93a7fcfe5a6ae8aadc1cd4d56f7d76b1366348e2 100644 (file)
 #include <asm/proc-armv/ptrace.h>
 
 extern void reset_cpu(ulong addr);
+#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
+extern void samsung_get_fclk(void);
+/* this is the same as PCLK, needed to calculate timer_load_val */
+extern unsigned int samsung_uartclk;
+int timer_load_val = 0;
+#endif
 
 /* for 10 ms clock period @ 50 MHz with 4 bit divider = 1/2 (default) */
 /* and prescaler = 16 */
@@ -190,8 +196,24 @@ int interrupt_init (void)
        /* use PWM Timer 4 because it has no output */
        /* prescaler for Timer 4 is 16 */
        rTCFG0 = 0x0f00;
+#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
+       if (timer_load_val == 0)
+       {
+               if (samsung_uartclk == 0)
+                       samsung_get_fclk();
+               /*
+                * for 10 ms clock period @ PCLK with 4 bit divider = 1/2
+                * (default) and prescaler = 16. Should be 10390
+                * @33.25MHz and 15625 @ 50 MHz
+                */
+               timer_load_val = samsung_uartclk/(2 * 16 * 100);
+       }
+       /* load value for 10 ms timeout */
+       lastdec = rTCNTB4 = timer_load_val;
+#elif defined(CONFIG_SMDK2410)
        /* load value for 10 ms timeout, assumes PCLK is 30 MHz !! */
        lastdec = rTCNTB4 = TIMER_LOAD_VAL;
+#endif
        /* auto load, manual update of Timer 4 */
        rTCON = 0x600000;
        /* auto load, start Timer 4 */
@@ -225,7 +247,11 @@ void udelay (unsigned long usec)
        ulong tmo;
 
        tmo = usec / 1000;
+#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
+       tmo *= (timer_load_val * 100);
+#elif defined(CONFIG_SMDK2410)
        tmo *= CFG_HZ;
+#endif
        tmo /= 1000;
 
        tmo += get_timer (0);
@@ -250,7 +276,11 @@ ulong get_timer_masked (void)
                timestamp += lastdec - now;
        } else {
                /* we have an overflow ... */
+#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
+               timestamp += lastdec + (timer_load_val * 100) - now;
+#elif defined(CONFIG_SMDK2410)
                timestamp += lastdec + TIMER_LOAD_VAL - now;
+#endif
        }
        lastdec = now;
 
@@ -262,7 +292,11 @@ void udelay_masked (unsigned long usec)
        ulong tmo;
 
        tmo = usec / 1000;
+#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
+       tmo *= (timer_load_val * 100);
+#elif defined(CONFIG_SMDK2410)
        tmo *= CFG_HZ;
+#endif
        tmo /= 1000;
 
        reset_timer_masked ();
index 53c00ebb3599cee25e9f352372685109b655c5fc..7cba3f2ec0613e87bc2f611e798ccaf66e0d34dd 100644 (file)
 
 unsigned int br[] = { 1562, 780, 390, 194, 32, 15 };
 
+#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
+/* dynamically determine the clock values */
+static unsigned int samsung_fclk = 0;
+unsigned int samsung_uartclk;
+void samsung_get_fclk(void)
+{
+       unsigned int mpllcon = rMPLLCON;
+       unsigned int clkdivn = rCLKDIVN & 3;
+       int clk_factor[4] = {1, 2, 2, 4};
+
+       /* the S3C2400 uses a 12 MHz xtal */
+       /* formula from page 6-22 */
+       samsung_fclk = ((12000000 * (8 + ((mpllcon & 0xff000) >> 12)))/((2 + ((mpllcon & 0x1f0) >> 4)) * (1 << (mpllcon & 3))));
+       samsung_uartclk = samsung_fclk/clk_factor[clkdivn];
+}
+#endif
+
 void serial_setbrg (void)
 {
        DECLARE_GLOBAL_DATA_PTR;
@@ -36,22 +53,11 @@ void serial_setbrg (void)
        unsigned int reg = 0;
 
 #if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
-       /* this assumes a PCLK of 50 MHz */
+       if (samsung_fclk == 0 || samsung_uartclk == 0)
+       samsung_get_fclk();
+
        /* value is calculated so : (int)(PCLK/16./baudrate) -1 */
-       if (gd->baudrate == 1200)
-               reg = 2603;
-       else if (gd->baudrate == 9600)
-               reg = 325;
-       else if (gd->baudrate == 19200)
-               reg = 162;
-       else if (gd->baudrate == 38400)
-               reg = 80;
-       else if (gd->baudrate == 57600)
-               reg = 53;
-       else if (gd->baudrate == 115200)
-               reg = 26;
-       else
-               hang ();
+       reg = samsung_uartclk/(16 * gd->baudrate) - 1;
 #elif defined(CONFIG_SMDK2410)
        /* this assumes a PCLK of 50.7 MHz */
        /* value is calculated so : (int)(PCLK/16./baudrate) -1 */
index 369c450a36d8a304af51d078f70bbb969a31c1d9..6208ba35a78f6eb99426071d6f124d927d41f9d8 100644 (file)
@@ -250,6 +250,7 @@ cpu_init_crit:
        bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS)
        bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM)
        orr     r0, r0, #0x00000002     @ set bit 2 (A) Align
+       orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache
        mcr     p15, 0, r0, c1, c0, 0
 
 
index 806fa4e26b93ce167c0784a50e05beebd7c8791b..2414f3406847a1d968d58223a72a57563af217e4 100644 (file)
@@ -115,6 +115,21 @@ typedef struct vidinfo {
 #define LCD_COLOR4     2
 #define LCD_COLOR8     3
 
+/*----------------------------------------------------------------------*/
+#ifdef CONFIG_KYOCERA_KCS057QV1AJ
+/*
+ *  Kyocera KCS057QV1AJ-G23. Passive, color, single scan.
+ */
+#define LCD_BPP        LCD_COLOR4
+
+static vidinfo_t panel_info = {
+    640, 480, 132, 99, CFG_HIGH, CFG_HIGH, CFG_HIGH, CFG_HIGH, CFG_HIGH,
+    LCD_BPP, 1, 0, 1, 0,  5, 0, 0, 0
+               /* wbl, vpw, lcdac, wbf */
+};
+#endif /* CONFIG_KYOCERA_KCS057QV1AJ */
+/*----------------------------------------------------------------------*/
+
 /*----------------------------------------------------------------------*/
 #ifdef CONFIG_NEC_NL6648AC33
 /*
index 808a10bb8589605599ef3fa5fd512d40b409360e..347f89538eef028ea4f91429e957214141e697e6 100644 (file)
@@ -1,15 +1,11 @@
 /*------------------------------------------------------------------------
- . smc91111.c
- . This is a driver for SMSC's 91C111 single-chip Ethernet device.
+ . 3c589.c
+ . This is a driver for 3Com's 3C589 (Etherlink III) PCMCIA Ethernet device.
  .
  . (C) Copyright 2002
  . Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  . Rolf Offermanns <rof@sysgo.de>
  .
- . Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
- .       Developed by Simple Network Magic Corporation (SNMC)
- . Copyright (C) 1996 by Erik Stahlman (ES)
- .
  . 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
  . along with this program; if not, write to the Free Software
  . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  .
- . Information contained in this file was obtained from the LAN91C111
- . manual from SMC.  To get a copy, if you really want one, you can find 
- . information under www.smsc.com.
- . 
- .
- . "Features" of the SMC chip:
- .   Integrated PHY/MAC for 10/100BaseT Operation
- .   Supports internal and external MII
- .   Integrated 8K packet memory
- .   EEPROM interface for configuration
- .
- . Arguments:
- .     io      = for the base address
- .     irq     = for the IRQ
- .
- . author:
- .     Erik Stahlman                           ( erik@vt.edu )
- .     Daris A Nevil                           ( dnevil@snmc.com )
- .
- .
- . Hardware multicast code from Peter Cammaert ( pc@denkart.be )
- .
- . Sources:
- .    o   SMSC LAN91C111 databook (www.smsc.com)
- .    o   smc9194.c by Erik Stahlman
- .    o   skeleton.c by Donald Becker ( becker@cesdis.gsfc.nasa.gov )
- .
- . History:
- .     10/17/01  Marco Hasewinkel Modify for DNP/1110
- .     07/25/01  Woojung Huh      Modify for ADS Bitsy
- .     04/25/01  Daris A Nevil    Initial public release through SMSC
- .     03/16/01  Daris A Nevil    Modified smc9194.c for use with LAN91C111
  ----------------------------------------------------------------------------*/
 
 #include <common.h>
@@ -147,7 +111,7 @@ typedef unsigned long int dword;
 /*------------------------------------------------------------------------
  .
  . The internal workings of the driver.  If you are changing anything
- . here with the SMC stuff, you should have the datasheet and know
+ . here with the 3Com stuff, you should have the datasheet and know
  . what you are doing.
  .
  -------------------------------------------------------------------------*/
@@ -210,21 +174,34 @@ static word read_eeprom(dword ioaddr, int index)
     return inw(ioaddr + 0xc);
 }
 
-static void el_get_mac_addr( word *mac_addr )
+static void el_get_mac_addr( unsigned char *mac_addr )
 {
        int i;
+       union
+       {
+               word w;
+               unsigned char b[2];
+       } wrd;
        unsigned char old_window = inw( EL_BASE_ADDR + EL3_STATUS ) >> 13;
        GO_WINDOW(0);
        VX_BUSY_WAIT;
        for (i = 0; i < 3; i++)
        {
-               *(mac_addr+i) = read_eeprom(EL_BASE_ADDR, 0xa+i);
+               wrd.w = read_eeprom(EL_BASE_ADDR, 0xa+i);
+#ifdef __BIG_ENDIAN
+               mac_addr[2*i]   = wrd.b[0];
+               mac_addr[2*i+1] = wrd.b[1];
+#else
+               mac_addr[2*i]   = wrd.b[1];
+               mac_addr[2*i+1] = wrd.b[0];
+#endif
        }
        GO_WINDOW(old_window);
        VX_BUSY_WAIT;
 }
 
 
+#if EL_DEBUG > 1
 static void print_packet( byte * buf, int length )
 {
         int i;
@@ -257,6 +234,7 @@ static void print_packet( byte * buf, int length )
         }
         PRINTK2("\n");
 }
+#endif /* EL_DEBUG > 1 */
 
 
 
@@ -283,16 +261,8 @@ static void el_reset(bd_t *bd)
        udelay(100000000);
 
        /* set mac addr */
-/*
-       outw(0xfeca, BASE + VX_W2_ADDR_0);
-       VX_BUSY_WAIT;
-       outw(0xadde, BASE + VX_W2_ADDR_2);
-       VX_BUSY_WAIT;
-       outw(0xefbe, BASE + VX_W2_ADDR_4);
-       VX_BUSY_WAIT;
-*/
        {
-               word *mac_addr = (word *)bd->bi_enetaddr;
+               unsigned char *mac_addr = bd->bi_enetaddr;
                int i;
                
                el_get_mac_addr( mac_addr );
@@ -301,10 +271,10 @@ static void el_reset(bd_t *bd)
                VX_BUSY_WAIT;
 
                printf("3C589 MAC Addr.: ");
-               for (i = 0; i < 3; i++)
+               for (i = 0; i < 6; i++)
                {
-                       printf("%04x", mac_addr[i]);
-                       outw(mac_addr[i], BASE + VX_W2_ADDR_0 + i*2);
+                       printf("%02x", mac_addr[i]);
+                       outb(mac_addr[i], BASE + VX_W2_ADDR_0 + i);
                        VX_BUSY_WAIT;
                }
                printf("\n\n");
@@ -362,6 +332,8 @@ static void el_reset(bd_t *bd)
        GO_WINDOW(1);
        VX_BUSY_WAIT;
 
+       /* wait for another 1ms */
+       udelay(100000000);
 }
 
        
@@ -419,6 +391,9 @@ int eth_rx()
        {
                /* error in packet -> discard */
                PRINTK("[ERROR] Invalid packet -> discarding\n");
+               PRINTK("-- error code 0x%02x\n", rx_status & ERR_MASK);
+               PRINTK("-- rx bytes 0x%04d\n", rx_status & ((1<<11) - 1));
+               PRINTK("[ERROR] Invalid packet -> discarding\n");
                outw( RX_DISCARD_TOP_PACK, BASE + VX_COMMAND );
                return 0;
        }
@@ -509,18 +484,23 @@ int eth_send(volatile void *packet, int length) {
        /* Second dword meaningless */
        outw(0x0, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);    
        
+#if EL_DEBUG > 1
        print_packet((byte *)buf, length);
+#endif
+
        /* write packet */
        {
-               unsigned int i, totdw;
+               unsigned int i, totw;
                
-               totdw = ((length + 3) >> 1);
-               PRINTK("Buffer: (totdw = %d)\n", totdw);
-               for (i = 0; i < totdw; i++) {
+               totw = ((length + 1) >> 1);
+               PRINTK("Buffer: (totw = %d)\n", totw);
+               for (i = 0; i < totw; i++) {
                        outw( *(buf+i), EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
-                       PRINTK("%04x ", *(buf+i));
-                       if ( ((i % 8) == 0) && (i != 0) )
-                               PRINTK("\n"); 
+                       udelay(10);
+               }
+               if(totw & 1)
+               {       /* pad to double word length */
+                       outw( 0, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
                        udelay(10);
                }
                PRINTK("\n\n");
@@ -528,11 +508,11 @@ int eth_send(volatile void *packet, int length) {
 
         /* wait for Tx complete */
        PRINTK("Waiting for Tx to complete...\n");
-        while((inw(EL_BASE_ADDR + VX_STATUS) & S_COMMAND_IN_PROGRESS) != 0)
+        while(((status = inw(EL_BASE_ADDR + VX_STATUS)) & S_COMMAND_IN_PROGRESS) != 0)
        {
                udelay(10);
        }
-       PRINTK("   ---> Tx completed\n");
+       PRINTK("   ---> Tx completed, status = 0x%04x\n", status);
 
        return length;
 }
index a2c3be788252294f01de0f3bb0da6293aecda697..d16affa3eae64e06a45346bedabfe587fa1e2f31 100644 (file)
 static const char version[] =
        "smc91111.c:v1.0 04/25/01 by Daris A Nevil (dnevil@snmc.com)\n";
 
-
 #define SMC_DEBUG 0
 
-
 /*------------------------------------------------------------------------
  .
  . Configuration options, for the experienced user to change.
@@ -122,7 +120,12 @@ static const char version[] =
 // Memory sizing constant
 #define LAN91C111_MEMORY_MULTIPLIER    (1024*2)
 
+#ifndef CONFIG_SMC91111_BASE
+#define CONFIG_SMC91111_BASE 0x20000300
+#endif
+
 #define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE 
+
 #define SMC_DEV_NAME "SMC91111"
 #define SMC_PHY_ADDR 0x0000
 #define SMC_ALLOC_MAX_TRY 5
@@ -204,13 +207,27 @@ static int smc_rcv(void);
  ------------------------------------------------------------
 */
 
-/** This is hardcoded for now.
- * Once the flash works correctly the mac addr. can be
- * fetched from FLASHBLOCK 1 / OFFSET 0x10 using 
- * smc_get_macaddr( smc_mac_addr );
+static char smc_mac_addr[] = {0x02, 0x80, 0xad, 0x20, 0x31, 0xb8};
+
+/*
+ * This function must be called before smc_open() if you want to override
+ * the default mac address.
  */
-byte   smc_mac_addr[6] = {0x08, 0x00, 0x3e, 0x26, 0x0a, 0x5b};
 
+void smc_set_mac_addr(const char *addr) {
+       int i;
+
+       for (i=0; i < sizeof(smc_mac_addr); i++){
+               smc_mac_addr[i] = addr[i];
+       }
+}
+
+/*
+ * smc_get_macaddr is no longer used. If you want to override the default
+ * mac address, call smc_get_mac_addr as a part of the board initialisation.
+ */
+
+#if 0
 void smc_get_macaddr( byte *addr ) {
        /* MAC ADDRESS AT FLASHBLOCK 1 / OFFSET 0x10 */
         unsigned char *dnp1110_mac = (unsigned char *) (0xE8000000 + 0x20010);
@@ -226,6 +243,7 @@ void smc_get_macaddr( byte *addr ) {
             addr[5] = *(dnp1110_mac+5);
         }
 }
+#endif /* 0 */
 
 /***********************************************
  * Show available memory                       *
@@ -645,12 +663,6 @@ static int smc_open()
 //     SMC_SELECT_BANK(0);
 //     SMC_outw(0, RPC_REG);
 
-       /*
-               According to Becker, I have to set the hardware address
-               at this point, because the (l)user can set it with an
-               ioctl.  Easily done...
-       */
-       SMC_SELECT_BANK( 1 );
 #ifdef USE_32_BIT
        for ( i = 0; i < 6; i += 2 ) {
                word address;
@@ -660,7 +672,7 @@ static int smc_open()
                SMC_outw( address, ADDR0_REG + i );
        }
 #else
-   for ( i = 0; i < 6; i ++ )
+       for ( i = 0; i < 6; i ++ )
                SMC_outb( smc_mac_addr[i], ADDR0_REG + i );
 #endif
 
@@ -675,8 +687,7 @@ insl32(r,b,l)
    dword *__b2;  
 
        __b2 = (dword *) b;  
-       for (__i = 0; __i < l; __i++) 
-   {  
+       for (__i = 0; __i < l; __i++) {  
                  *(__b2 + __i) = *(dword *)(r+0x10000300);  
        }  
 }
@@ -701,7 +712,7 @@ static int smc_rcv()
        word    packet_length;
        int     is_error = 0;
 #ifdef USE_32_BIT
-   dword stat_len;
+       dword stat_len;
 #endif
 
 
@@ -719,9 +730,9 @@ static int smc_rcv()
 
        /* First two words are status and packet_length */
 #ifdef USE_32_BIT
-   stat_len = SMC_inl(SMC91111_DATA_REG);
-   status = stat_len & 0xffff;
-   packet_length = stat_len >> 16;
+       stat_len = SMC_inl(SMC91111_DATA_REG);
+       status = stat_len & 0xffff;
+       packet_length = stat_len >> 16;
 #else
        status          = SMC_inw( SMC91111_DATA_REG );
        packet_length   = SMC_inw( SMC91111_DATA_REG );
@@ -751,14 +762,14 @@ static int smc_rcv()
                   performance  */
                SMC_insl( SMC91111_DATA_REG , NetRxPackets[0], packet_length >> 2 );
                /* read the left over bytes */
-          if (packet_length & 3) 
-      {
-         int i;
-                  byte *tail = NetRxPackets[0] + (packet_length & ~3);
-                  dword leftover = SMC_inl(SMC91111_DATA_REG);
-                  for (i=0; i<(packet_length & 3); i++) 
-                          *tail++ = (byte) (leftover >> (8*i)) & 0xff;
-          }           
+               if (packet_length & 3) {
+                       int i;
+
+                       byte *tail = NetRxPackets[0] + (packet_length & ~3);
+                       dword leftover = SMC_inl(SMC91111_DATA_REG);
+                       for (i=0; i<(packet_length & 3); i++) 
+                               *tail++ = (byte) (leftover >> (8*i)) & 0xff;
+               }              
 #else
                PRINTK3(" Reading %d words and %d byte(s) \n",
                        (packet_length >> 1 ), packet_length & 1 );
@@ -1160,7 +1171,7 @@ static void smc_write_phy_register(byte phyreg, word phydata)
  .-------------------------------------------------------------*/
 static void smc_wait_ms(unsigned int ms)
 {
-       udelay(ms*100000);
+       udelay(ms*1000);
 }
 
 
index e517957704386a97b35f1d82250853ef5d17547a..dbb32f0bef3ea6d74874437b79136d1a49a5749b 100644 (file)
 #include <asm/types.h>
 #include <config.h>
 
+/*
+ * This function may be called by the board specific initialisation code
+ * in order to override the default mac address.
+ */
+
+void smc_set_mac_addr(const char *addr);
+
 
 /* I want some simple types */
 
index e8adb833aca7148e0fd9c0bb959d125fce023aa3..8efd826ad6b5cf4cc2fb0074c2a6f8171b4b0986 100644 (file)
@@ -300,6 +300,12 @@ extern void        NetReceive(volatile uchar *, int);
 /* Print an IP address on the console */
 extern void    print_IPaddr (IPaddr_t);
 
+/* Read an IP address from memory, independend of byte order and alignment */
+IPaddr_t NetReadIP(volatile uchar *);
+
+/* Write an IP address to memory, independend of byte order and alignment */
+void NetWriteIP(volatile uchar *, IPaddr_t);
+
 /* Convert an IP address to a string */
 extern void    ip_to_string (IPaddr_t x, char *s);
 
index fc6a0b6655e7b10633d36913258e77fd7d338384..c17938271682ec44b997be2e3d1d88157b359218 100644 (file)
--- a/net/arp.c
+++ b/net/arp.c
@@ -96,15 +96,15 @@ ArpRequest (void)
        arp->ar_op  = htons(ARPOP_REQUEST);
 
        memcpy (&arp->ar_data[0], NetOurEther, 6);      /* source ET addr       */
-       memcpy (&arp->ar_data[6], &NetOurIP, 4);        /* source IP 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)) {
-           memcpy (&arp->ar_data[16], &NetOurGatewayIP, 4);
+           NetWriteIP((uchar*)&arp->ar_data[16], NetOurGatewayIP);
        } else {
-           memcpy (&arp->ar_data[16], &NetServerIP, 4);
+           NetWriteIP((uchar*)&arp->ar_data[16], NetServerIP);
        }
 
 
index dc481f30e0362db1c8dc7325dc45db5ba11c6176..b51a9fe38110e182d9cebc572e42c76d93d7c886 100644 (file)
@@ -62,13 +62,13 @@ static void DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len);
 char *dhcpmsg2str(int type)
 {
        switch (type) {
-       case 1: return "DHCPDISCOVER"; break;
-       case 2: return "DHCPOFFER"; break;
-       case 3: return "DHCPREQUEST"; break;
-       case 4: return "DHCPDECLINE"; break;
-       case 5: return "DHCPACK"; break;
-       case 6: return "DHCPNACK"; break;
-       case 7: return "DHCPRELEASE"; break;
+       case 1:  return "DHCPDISCOVER"; break;
+       case 2:  return "DHCPOFFER";    break;
+       case 3:  return "DHCPREQUEST";  break;
+       case 4:  return "DHCPDECLINE";  break;
+       case 5:  return "DHCPACK";      break;
+       case 6:  return "DHCPNACK";     break;
+       case 7:  return "DHCPRELEASE";  break;
        default: return "UNKNOWN/INVALID MSG TYPE"; break;
        }
 }
@@ -87,21 +87,25 @@ static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)
 
        if (dest != PORT_BOOTPC || src != PORT_BOOTPS)
                retval = -1;
-       if (len < sizeof (Bootp_t) - OPT_SIZE)
+       else if (len < sizeof (Bootp_t) - OPT_SIZE)
                retval = -2;
-       if (bp->bp_op != OP_BOOTREQUEST &&
+       else if (bp->bp_op != OP_BOOTREQUEST &&
            bp->bp_op != OP_BOOTREPLY &&
            bp->bp_op != DHCP_OFFER &&
            bp->bp_op != DHCP_ACK &&
            bp->bp_op != DHCP_NAK ) {
                retval = -3;
        }
-       if (bp->bp_htype != HWT_ETHER)
+       else if (bp->bp_htype != HWT_ETHER)
                retval = -4;
-       if (bp->bp_hlen != HWL_ETHER)
+       else if (bp->bp_hlen != HWL_ETHER)
                retval = -5;
-       if (bp->bp_id != htonl(BootpID))
-               retval = -6;
+       else {
+               ulong id;
+               memcpy(&id, &bp->bp_id, sizeof(bp->bp_id));
+               if (ntohl(id) != BootpID)
+                       retval = -6;
+       }
 
        debug ("Filtering pkt = %d\n", retval);
 
@@ -113,8 +117,8 @@ static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)
  */
 void BootpCopyNetParams(Bootp_t *bp)
 {
-       memcpy (&NetOurIP,    &bp->bp_yiaddr, 4);
-       memcpy (&NetServerIP, &bp->bp_siaddr, 4);
+       NetOurIP    = NetReadIP((vu_char*)&bp->bp_yiaddr);
+       NetServerIP = NetReadIP((vu_char*)&bp->bp_siaddr);
        memcpy (NetServerEther, ((Ethernet_t *)NetRxPkt)->et_src, 6);
        copy_filename (BootFile, bp->bp_file, sizeof(BootFile));
 
@@ -153,14 +157,14 @@ static void BootpVendorFieldProcess(u8 *ext)
     /* Fixed length fields */
        case 1:         /* Subnet mask                                  */
                if (NetOurSubnetMask == 0)
-                   memcpy(&NetOurSubnetMask, ext+2, 4);
+                       NetOurSubnetMask = NetReadIP(ext+2);
                break;
        case 2:         /* Time offset - Not yet supported              */
                break;
     /* Variable length fields */
        case 3:         /* Gateways list                                */
                if (NetOurGatewayIP == 0) {
-                   memcpy(&NetOurGatewayIP, ext+2, 4);
+                       NetOurGatewayIP = NetReadIP(ext+2);
                }
                break;
        case 4:         /* Time server - Not yet supported              */
@@ -169,7 +173,7 @@ static void BootpVendorFieldProcess(u8 *ext)
                break;
        case 6:
                if (NetOurDNSIP == 0) {
-                   memcpy(&NetOurDNSIP, ext+2, 4);
+                       NetOurDNSIP = NetReadIP(ext+2);
                }
                break;
        case 7:         /* Log server - Not yet supported               */
@@ -190,7 +194,10 @@ static void BootpVendorFieldProcess(u8 *ext)
                }
                break;
        case 13:        /* Boot file size                               */
-               memcpy(&NetBootFileSize, ext+2, size);
+               if (size == 2)
+                       NetBootFileSize = ntohs(*(ushort*)(ext+2));
+               else if (size == 4)
+                       NetBootFileSize = ntohl(*(ulong*)(ext+2));
                break;
        case 14:        /* Merit dump file - Not yet supported          */
                break;
@@ -279,6 +286,10 @@ static void BootpVendorProcess(u8 *ext, int size)
     if (NetOurNISDomain[0]) {
         printf("NetOurNISDomain : %s\n", NetOurNISDomain);
     }
+
+    if (NetBootFileSize) {
+       printf("NetBootFileSize: %d\n", NetBootFileSize);
+    }
 #endif /* DEBUG_BOOTP_EXT */
 }
 
@@ -290,6 +301,7 @@ BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
 {
        Bootp_t *bp;
        char    *s;
+       ulong   vendmagic;
 
        debug ("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%d)\n",
                src, dest, len, sizeof (Bootp_t));
@@ -308,9 +320,10 @@ BootpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
 
        BootpCopyNetParams(bp);         /* Store net parameters from reply */
 
-       /* Retrieve extended informations (we must parse the vendor area) */
-       if ((*(uint *)bp->bp_vend) == htonl(BOOTP_VENDOR_MAGIC))
-           BootpVendorProcess(&bp->bp_vend[4], len);
+       /* Retrieve extended information (we must parse the vendor area) */
+       memcpy(&vendmagic, bp->bp_vend, sizeof(vendmagic));
+       if (ntohl(vendmagic) == BOOTP_VENDOR_MAGIC)
+               BootpVendorProcess(&bp->bp_vend[4], len);
 
        NetSetTimeout(0, (thand_f *)0);
 
@@ -520,6 +533,7 @@ BootpRequest (void)
        volatile uchar *pkt, *iphdr;
        Bootp_t *bp;
        int ext_len, pktlen, iplen;
+       ulong id;
 
 #if (CONFIG_COMMANDS & CFG_CMD_DHCP)
        dhcp_state = INIT;
@@ -622,10 +636,10 @@ BootpRequest (void)
        bp->bp_hlen = HWL_ETHER;
        bp->bp_hops = 0;
        bp->bp_secs = htons(get_timer(0) / CFG_HZ);
-       bp->bp_ciaddr = 0;
-       bp->bp_yiaddr = 0;
-       bp->bp_siaddr = 0;
-       bp->bp_giaddr = 0;
+       NetWriteIP((vu_char*)&bp->bp_ciaddr, 0);
+       NetWriteIP((vu_char*)&bp->bp_yiaddr, 0);
+       NetWriteIP((vu_char*)&bp->bp_siaddr, 0);
+       NetWriteIP((vu_char*)&bp->bp_giaddr, 0);
        memcpy (bp->bp_chaddr, NetOurEther, 6);
        copy_filename (bp->bp_file, BootFile, sizeof(bp->bp_file));
 
@@ -645,7 +659,8 @@ BootpRequest (void)
                | ((ulong)NetOurEther[4] << 8)
                | (ulong)NetOurEther[5];
        BootpID += get_timer(0);
-       bp->bp_id = htonl(BootpID);
+       id = htonl(BootpID);
+       memcpy(&bp->bp_id, &id, sizeof(id));
 
        /*
         * Calculate proper packet lengths taking into account the
@@ -726,7 +741,10 @@ void DhcpOptionsProcess(char *popt)
 
 static int DhcpMessageType(unsigned char *popt)
 {
-       if ((*(uint *)popt) != htonl(BOOTP_VENDOR_MAGIC))
+       ulong vendmagic;
+
+       memcpy(&vendmagic, popt, sizeof(vendmagic));
+       if (ntohl(vendmagic) != BOOTP_VENDOR_MAGIC)
                return -1;
 
        popt += 4;
@@ -770,7 +788,7 @@ void DhcpSendRequestPkt(Bootp_t *bp_offer)
         * ID is the id of the OFFER packet
         */
 
-       bp->bp_id = bp_offer->bp_id;
+       memcpy(&bp->bp_id, &bp_offer->bp_id, sizeof(bp->bp_id));
 
        /*
         * Copy options from OFFER packet if present
@@ -792,6 +810,7 @@ static void
 DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
 {
        Bootp_t *bp = (Bootp_t *)pkt;
+       ulong vendmagic;
 
        debug ("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n",
                src, dest, len, dhcp_state);
@@ -820,7 +839,8 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
                        debug ("TRANSITIONING TO REQUESTING STATE\n");
                        dhcp_state = REQUESTING;
 #if 0
-                       if ((*(uint *)bp->bp_vend) == BOOTP_VENDOR_MAGIC)
+                       memcpy(&vendmagic, bp->bp_vend, sizeof(vendmagic));
+                       if (ntohl(vendmagic) == BOOTP_VENDOR_MAGIC)
                                DhcpOptionsProcess(&bp->bp_vend[4]);
 
 #endif
@@ -840,7 +860,8 @@ DhcpHandler(uchar * pkt, unsigned dest, unsigned src, unsigned len)
                if ( DhcpMessageType(bp->bp_vend) == DHCP_ACK ) {
                        char *s;
 
-                       if ((*(uint *)bp->bp_vend) == BOOTP_VENDOR_MAGIC)
+                       memcpy(&vendmagic, bp->bp_vend, sizeof(vendmagic));
+                       if (ntohl(vendmagic) == BOOTP_VENDOR_MAGIC)
                                DhcpOptionsProcess(&bp->bp_vend[4]);
                        BootpCopyNetParams(bp); /* Store net params from reply */
                        dhcp_state = BOUND;
index b2389f7abc9ed4726a1e2fe24333bed869a7750b..69c7ed0f8412fd55fea55e95f2c3df277a2608a5 100644 (file)
--- a/net/net.c
+++ b/net/net.c
@@ -340,6 +340,7 @@ NetReceive(volatile uchar * pkt, int len)
        Ethernet_t *et;
        IP_t    *ip;
        ARP_t   *arp;
+       IPaddr_t tmp;
        int     x;
 
 
@@ -398,8 +399,12 @@ NetReceive(volatile uchar * pkt, int len)
                        return;
                }
 
-               if (NetOurIP == 0 ||
-                   *((IPaddr_t *)&arp->ar_data[16]) != NetOurIP) {
+               if (NetOurIP == 0) {
+                       return;
+               }
+
+               tmp = NetReadIP((uchar*)&arp->ar_data[16]);
+               if (tmp != NetOurIP) {
                        return;
                }
 
@@ -411,9 +416,9 @@ NetReceive(volatile uchar * pkt, int len)
                        NetSetEther((uchar *)et, et->et_src, PROT_ARP);
                        arp->ar_op = htons(ARPOP_REPLY);
                        memcpy (&arp->ar_data[10], &arp->ar_data[0], 6);
-                       memcpy (&arp->ar_data[0], NetOurEther, 6);
                        memcpy (&arp->ar_data[16], &arp->ar_data[6], 4);
-                       memcpy (&arp->ar_data[6], &NetOurIP, 4);
+                       memcpy (&arp->ar_data[0], NetOurEther, 6);
+                       NetWriteIP (&arp->ar_data[6], NetOurIP);
                        NetSendPacket((uchar *)et,((uchar *)arp-pkt)+ARP_HDR_SIZE);
                        return;
                case ARPOP_REPLY:               /* set TFTP server eth addr     */
@@ -447,8 +452,8 @@ NetReceive(volatile uchar * pkt, int len)
 
                        printf("invalid RARP header\n");
                } else {
-                       memcpy (&NetOurIP,      &arp->ar_data[16], 4);
-                       memcpy (&NetServerIP,   &arp->ar_data[6],  4);
+                       NetOurIP    = NetReadIP((uchar*)&arp->ar_data[16]);
+                       NetServerIP = NetReadIP((uchar*)&arp->ar_data[6]);
                        memcpy (NetServerEther, &arp->ar_data[0],  6);
 
                        (*packetHandler)(0,0,0,0);
@@ -481,9 +486,8 @@ NetReceive(volatile uchar * pkt, int len)
                        printf("checksum bad\n");
                        return;
                }
-               if (NetOurIP &&
-                   ip->ip_dst != NetOurIP &&
-                   ip->ip_dst != 0xFFFFFFFF) {
+               tmp = NetReadIP((uchar*)&ip->ip_dst);
+               if (NetOurIP && tmp != NetOurIP && tmp != 0xFFFFFFFF) {
                        return;
                }
                /*
@@ -638,8 +642,8 @@ NetSetIP(volatile uchar * xip, IPaddr_t dest, int dport, int sport, int len)
        ip->ip_ttl   = 255;
        ip->ip_p     = 17;              /* UDP */
        ip->ip_sum   = 0;
-       ip->ip_src   = NetOurIP;        /* already in network byte order */
-       ip->ip_dst   = dest;            /* - "" - */
+       NetWriteIP ((uchar*)&ip->ip_src, NetOurIP);
+       NetWriteIP ((uchar*)&ip->ip_dst, dest);
        ip->udp_src  = htons(sport);
        ip->udp_dst  = htons(dport);
        ip->udp_len  = htons(8 + len);
@@ -675,7 +679,7 @@ void ip_to_string (IPaddr_t x, char *s)
 
 void print_IPaddr (IPaddr_t x)
 {
-    char tmp[12];
+    char tmp[16];
 
     ip_to_string(x, tmp);
 
@@ -701,3 +705,27 @@ IPaddr_t getenv_IPaddr (char *var)
 
        return (htonl(addr));
 }
+
+IPaddr_t
+NetReadIP(volatile uchar * from)
+{
+       IPaddr_t ip;
+       int i;
+
+       ip = 0;
+       for (i = 0; i < 4; i++) 
+               ip = (ip << 8) | *from++;
+
+       return ip;
+}
+
+void
+NetWriteIP(volatile uchar * to, IPaddr_t ip)
+{
+       int i;
+
+       for (i = 0; i < 4; i++) {
+               *to++ = ip >> 24;
+               ip <<= 8;
+       }
+}
index 3aa745b5f158db91126712ccd96eb6835411b7d0..ec1dccb813978df5472cf83a4a38c21f671f67ef 100644 (file)
@@ -152,6 +152,8 @@ TftpSend (void)
 static void
 TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
 {
+       ushort proto;
+
        if (dest != TftpOurPort) {
                return;
        }
@@ -163,7 +165,9 @@ TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
                return;
        }
        len -= 2;
-       switch (ntohs(*((ushort *)pkt)++)) {
+       /* warning: don't use increment (++) in ntohs() macros!! */
+       proto = *((ushort *)pkt)++;
+       switch (ntohs(proto)) {
 
        case TFTP_RRQ:
        case TFTP_WRQ: