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.
#
# we load ourself to 33F0'0000
#
-# download areas is 3300'0000
+# download area is 3300'0000
#
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x0c000100;
- return 1;
+ return 0;
}
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;
}
#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)
{
#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)
{
* 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);
/* flush I/D-cache */
i = 0;
asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (i));
-#endif
return (0);
}
return (0);
}
-#ifdef USE_920T_MMU
void icache_enable (void)
{
ulong reg;
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;
#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 */
/* 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 */
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);
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;
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 ();
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;
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 */
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
#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
/*
/*------------------------------------------------------------------------
- . 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>
/*------------------------------------------------------------------------
.
. 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.
.
-------------------------------------------------------------------------*/
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;
}
PRINTK2("\n");
}
+#endif /* EL_DEBUG > 1 */
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 );
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");
GO_WINDOW(1);
VX_BUSY_WAIT;
+ /* wait for another 1ms */
+ udelay(100000000);
}
{
/* 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;
}
/* 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");
/* 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;
}
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.
// 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
------------------------------------------------------------
*/
-/** 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);
addr[5] = *(dnp1110_mac+5);
}
}
+#endif /* 0 */
/***********************************************
* Show available memory *
// 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;
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
dword *__b2;
__b2 = (dword *) b;
- for (__i = 0; __i < l; __i++)
- {
+ for (__i = 0; __i < l; __i++) {
*(__b2 + __i) = *(dword *)(r+0x10000300);
}
}
word packet_length;
int is_error = 0;
#ifdef USE_32_BIT
- dword stat_len;
+ dword stat_len;
#endif
/* 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 );
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 );
.-------------------------------------------------------------*/
static void smc_wait_ms(unsigned int ms)
{
- udelay(ms*100000);
+ udelay(ms*1000);
}
#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 */
/* 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);
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);
}
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;
}
}
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);
*/
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));
/* 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 */
break;
case 6:
if (NetOurDNSIP == 0) {
- memcpy(&NetOurDNSIP, ext+2, 4);
+ NetOurDNSIP = NetReadIP(ext+2);
}
break;
case 7: /* Log server - Not yet supported */
}
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;
if (NetOurNISDomain[0]) {
printf("NetOurNISDomain : %s\n", NetOurNISDomain);
}
+
+ if (NetBootFileSize) {
+ printf("NetBootFileSize: %d\n", NetBootFileSize);
+ }
#endif /* DEBUG_BOOTP_EXT */
}
{
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));
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);
volatile uchar *pkt, *iphdr;
Bootp_t *bp;
int ext_len, pktlen, iplen;
+ ulong id;
#if (CONFIG_COMMANDS & CFG_CMD_DHCP)
dhcp_state = INIT;
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));
| ((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
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;
* 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
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);
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
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;
Ethernet_t *et;
IP_t *ip;
ARP_t *arp;
+ IPaddr_t tmp;
int x;
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;
}
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 */
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);
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;
}
/*
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);
void print_IPaddr (IPaddr_t x)
{
- char tmp[12];
+ char tmp[16];
ip_to_string(x, tmp);
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;
+ }
+}
static void
TftpHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
{
+ ushort proto;
+
if (dest != TftpOurPort) {
return;
}
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: