* Patch by Nicolas Lacressonniere, 11 Jun 2003:
  Modifications for Atmel AT91RM9200DK ARM920T based development kit
  - Add Atmel DataFlash support for reading and writing.
  - Add possibility to boot a Linux from DataFlash with BOOTM command.
  - Add Flash detection on Atmel AT91RM9200DK
    (between Atmel AT49BV1614 and AT49BV1614A flashes)
  - Replace old Ethernet PHY layer functions
  - Change link address

* Patch by Frank Smith, 9 Jun 2003:
  use CRIT_EXCEPTION for machine check on 4xx

* Patch by Detlev Zundel, 13 Jun 2003:
  added implementation of the "carinfo" command in cmd_immap.c
diff --git a/CHANGELOG b/CHANGELOG
index 0cecad3..8cc4113 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,21 @@
 Changes since U-Boot 0.3.1:
 ======================================================================
 
+* Patch by Nicolas Lacressonniere, 11 Jun 2003:
+  Modifications for Atmel AT91RM9200DK ARM920T based development kit
+  - Add Atmel DataFlash support for reading and writing.
+  - Add possibility to boot a Linux from DataFlash with BOOTM command. 
+  - Add Flash detection on Atmel AT91RM9200DK
+    (between Atmel AT49BV1614 and AT49BV1614A flashes)
+  - Replace old Ethernet PHY layer functions
+  - Change link address
+
+* Patch by Frank Smith, 9 Jun 2003:
+  use CRIT_EXCEPTION for machine check on 4xx
+
+* Patch by Detlev Zundel, 13 Jun 2003:
+  added implementation of the "carinfo" command in cmd_immap.c
+
 * Fix CONFIG_NET_MULTI support in include/net.h
 
 * Patches by Kyle Harris, 13 Mar 2003:
diff --git a/README b/README
index 135f022..453ef7a 100644
--- a/README
+++ b/README
@@ -151,6 +151,7 @@
 - board/RPXClassic
 		Files specific to RPXClassic boards
 - board/RPXlite	Files specific to RPXlite    boards
+- board/at91rm9200dk Files specific to AT91RM9200DK boards
 - board/c2mon	Files specific to c2mon	     boards
 - board/cmi	Files specific to cmi        boards
 - board/cogent	Files specific to Cogent     boards
@@ -352,7 +353,7 @@
 		CONFIG_HHP_CRADLE,  CONFIG_DNP1110,    CONFIG_EP7312,
 		CONFIG_IMPA7,       CONFIG_LART,       CONFIG_LUBBOCK,
 		CONFIG_SHANNON,     CONFIG_SMDK2400,   CONFIG_SMDK2410,
-		CONFIG_TRAB
+		CONFIG_TRAB,	    CONFIG_AT91RM9200DK
 
 
 - CPU Module Type: (if CONFIG_COGENT is defined)
@@ -1248,6 +1249,13 @@
 		the environment like the autoscript function or the
 		boot command first.
 
+- DataFlash Support
+		CONFIG_HAS_DATAFLASH
+
+                Defining this option enables DataFlash features and
+                allows to read/write in Dataflash via the standard
+                commands cp, md...
+
 - Show boot progress
 		CONFIG_SHOW_BOOT_PROGRESS
 
@@ -1801,6 +1809,7 @@
     GENIETV_config	  TQM823L_config	PIP405_config
     GEN860T_config	  EBONY_config		FPS860L_config
     ELPT860_config	  cmi_mpc5xx_config	NETVIA_config
+    at91rm9200dk_config
 
 Note: for some board special configuration names may exist; check  if
       additional  information is available from the board vendor; for
diff --git a/board/at91rm9200dk/at91rm9200dk.c b/board/at91rm9200dk/at91rm9200dk.c
index 07def18..ffd9687 100644
--- a/board/at91rm9200dk/at91rm9200dk.c
+++ b/board/at91rm9200dk/at91rm9200dk.c
@@ -30,28 +30,35 @@
  * Miscelaneous platform dependent initialisations
  */
 
-int board_init(void)
-  {
-  DECLARE_GLOBAL_DATA_PTR;
+int board_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
 
-    /* memory and cpu-speed are setup before relocation */
-    /* so we do _nothing_ here */
+	/* Enable Ctrlc */
+	console_init_f ();
 
-    /* arch number of AT91RM9200DK-Board */
-    gd->bd->bi_arch_number = 251;
-    /* adress of boot parameters */
-    gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+	/* Correct IRDA resistor problem */
+	/* Set PA23_TXD in Output */
+	(AT91PS_PIO) AT91C_BASE_PIOA->PIO_OER = AT91C_PA23_TXD2;
 
-    return 0;
+	/* memory and cpu-speed are setup before relocation */
+	/* so we do _nothing_ here */
+
+	/* arch number of AT91RM9200DK-Board */
+	gd->bd->bi_arch_number = 251;
+	/* adress of boot parameters */
+	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+
+	return 0;
 }
 
-int dram_init(void)
+int dram_init (void)
 {
-  DECLARE_GLOBAL_DATA_PTR;
+	DECLARE_GLOBAL_DATA_PTR;
 
-  gd->bd->bi_dram[0].start = PHYS_SDRAM;
-  gd->bd->bi_dram[0].size  = PHYS_SDRAM_SIZE;
-  return 0;
+	gd->bd->bi_dram[0].start = PHYS_SDRAM;
+	gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE;
+	return 0;
 }
 
 /*
@@ -59,47 +66,47 @@
  * The NAND lives in the CS2* space
  */
 #if (CONFIG_COMMANDS & CFG_CMD_NAND)
-extern void
-nand_probe(ulong physadr);
+extern void nand_probe (ulong physadr);
 
-#define AT91_SMARTMEDIA_BASE 0x40000000  /* physical address to access memory on NCS3 */
-void
-nand_init(void)
+#define AT91_SMARTMEDIA_BASE 0x40000000	/* physical address to access memory on NCS3 */
+void nand_init (void)
 {
 	/* Setup Smart Media, fitst enable the address range of CS3 */
-        *AT91C_EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia;
-        /* set the bus interface characteristics based on
-           tDS Data Set up Time 30 - ns
-           tDH Data Hold Time 20 - ns
-           tALS ALE Set up Time 20 - ns
-           16ns at 60 MHz ~= 3  */
+	*AT91C_EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia;
+	/* set the bus interface characteristics based on
+	   tDS Data Set up Time 30 - ns
+	   tDH Data Hold Time 20 - ns
+	   tALS ALE Set up Time 20 - ns
+	   16ns at 60 MHz ~= 3  */
 /*memory mapping structures */
 #define SM_ID_RWH	(5 << 28)
 #define SM_RWH		(1 << 28)
 #define SM_RWS		(0 << 24)
 #define SM_TDF		(1 << 8)
 #define SM_NWS		(3)
-        AT91C_BASE_SMC2->SMC2_CSR[3] = ( SM_RWH|SM_RWS | AT91C_SMC2_ACSS_STANDARD |
-                                         AT91C_SMC2_DBW_8 | SM_TDF |
-                                         AT91C_SMC2_WSEN | SM_NWS);
+	AT91C_BASE_SMC2->SMC2_CSR[3] = (SM_RWH | SM_RWS |
+		AT91C_SMC2_ACSS_STANDARD | AT91C_SMC2_DBW_8 |
+		SM_TDF | AT91C_SMC2_WSEN | SM_NWS);
 
-        /* enable the SMOE line PC0=SMCE, A21=CLE, A22=ALE */
-        *AT91C_PIOC_ASR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE;
-        *AT91C_PIOC_PDR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE | AT91C_PC3_BFBAA_SMWE;
+	/* enable the SMOE line PC0=SMCE, A21=CLE, A22=ALE */
+	*AT91C_PIOC_ASR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE |
+		AT91C_PC3_BFBAA_SMWE;
+	*AT91C_PIOC_PDR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE |
+		AT91C_PC3_BFBAA_SMWE;
 
 	/* Configure PC2 as input (signal READY of the SmartMedia) */
-        *AT91C_PIOC_PER = AT91C_PC2_BFAVD;  /* enable direct output enable */
-        *AT91C_PIOC_ODR = AT91C_PC2_BFAVD;  /* disable output */
+	*AT91C_PIOC_PER = AT91C_PC2_BFAVD;	/* enable direct output enable */
+	*AT91C_PIOC_ODR = AT91C_PC2_BFAVD;	/* disable output */
 
 	/* Configure PB1 as input (signal Card Detect of the SmartMedia) */
-        *AT91C_PIOB_PER = AT91C_PIO_PB1;  /* enable direct output enable */
-        *AT91C_PIOB_ODR = AT91C_PIO_PB1;  /* disable output */
+	*AT91C_PIOB_PER = AT91C_PIO_PB1;	/* enable direct output enable */
+	*AT91C_PIOB_ODR = AT91C_PIO_PB1;	/* disable output */
 
-        if (*AT91C_PIOB_PDSR & AT91C_PIO_PB1)
-          printf ("No ");
-        printf ("SmartMedia card inserted\n");
+	if (*AT91C_PIOB_PDSR & AT91C_PIO_PB1)
+		printf ("No ");
+	printf ("SmartMedia card inserted\n");
 
-	printf("Probing at 0x%.8x\n", AT91_SMARTMEDIA_BASE);
-	nand_probe(AT91_SMARTMEDIA_BASE);
+	printf ("Probing at 0x%.8x\n", AT91_SMARTMEDIA_BASE);
+	nand_probe (AT91_SMARTMEDIA_BASE);
 }
 #endif
diff --git a/board/at91rm9200dk/config.mk b/board/at91rm9200dk/config.mk
index a682451..009b4d7 100644
--- a/board/at91rm9200dk/config.mk
+++ b/board/at91rm9200dk/config.mk
@@ -1,2 +1,2 @@
-TEXT_BASE = 0x21fa0000
+TEXT_BASE = 0x21f00000
 
diff --git a/board/at91rm9200dk/flash.c b/board/at91rm9200dk/flash.c
index 6497f11..4d4524f 100644
--- a/board/at91rm9200dk/flash.c
+++ b/board/at91rm9200dk/flash.c
@@ -31,11 +31,40 @@
 ulong myflush(void);
 
 
+/* Flash Organization Structure */
+typedef struct OrgDef
+{
+	unsigned int sector_number;
+	unsigned int sector_size;
+} OrgDef;
+
+
+/* Flash Organizations */
+OrgDef OrgAT49BV16x4[] =
+{
+	{ 8, 8*1024 }, /* 8 * 8kBytes sectors */
+	{ 2, 32*1024 }, /* 2 * 32kBytes sectors */	
+	{ 30, 64*1024 } /* 30 * 64kBytes sectors */	
+};
+
+OrgDef OrgAT49BV16x4A[] =
+{
+	{ 8, 8*1024 }, /* 8 * 8kBytes sectors */	
+	{ 31, 64*1024 } /* 31 * 64kBytes sectors */	
+};
+
+
 #define FLASH_BANK_SIZE 0x200000	/* 2 MB */
 #define MAIN_SECT_SIZE  0x10000		/* 64 KB */
 
 flash_info_t    flash_info[CFG_MAX_FLASH_BANKS];
 
+/* AT49BV1614A Codes */
+#define FLASH_CODE1		0xAA
+#define FLASH_CODE2		0x55
+#define ID_IN_CODE		0x90
+#define ID_OUT_CODE		0xF0
+
 
 #define CMD_READ_ARRAY		0x00F0
 #define CMD_UNLOCK1		0x00AA
@@ -48,6 +77,9 @@
 #define MEM_FLASH_ADDR1		(*(volatile u16 *)(CFG_FLASH_BASE + (0x00005555<<1)))
 #define MEM_FLASH_ADDR2		(*(volatile u16 *)(CFG_FLASH_BASE + (0x00002AAA<<1)))
 
+#define IDENT_FLASH_ADDR1	(*(volatile u16 *)(CFG_FLASH_BASE + (0x0000555<<1)))
+#define IDENT_FLASH_ADDR2	(*(volatile u16 *)(CFG_FLASH_BASE + (0x0000AAA<<1)))
+
 #define BIT_ERASE_DONE		0x0080
 #define BIT_RDY_MASK		0x0080
 #define BIT_PROGRAM_ERROR	0x0020
@@ -59,339 +91,375 @@
 
 /*-----------------------------------------------------------------------
  */
-
-ulong flash_init(void)
+void flash_identification (flash_info_t * info)
 {
-    int i, j;
-    ulong size = 0;
+	volatile u16 manuf_code, device_code, add_device_code;
 
-    for (i = 0; i < CFG_MAX_FLASH_BANKS; i++)
-    {
-	ulong flashbase = 0;
-	flash_info[i].flash_id =
-	  (ATM_MANUFACT & FLASH_VENDMASK) |
-	  (ATM_ID_BV1614 & FLASH_TYPEMASK);
-	flash_info[i].size = FLASH_BANK_SIZE;
-	flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
-	memset(flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
-	if (i == 0)
-	  flashbase = PHYS_FLASH_1;
-	else
-	  panic("configured to many flash banks!\n");
-	for (j = 0; j < flash_info[i].sector_count; j++)
-	{
+	IDENT_FLASH_ADDR1 = FLASH_CODE1;
+	IDENT_FLASH_ADDR2 = FLASH_CODE2;
+	IDENT_FLASH_ADDR1 = ID_IN_CODE;
 
-	    if (j <= 9)
-	    {
-		/* 1st to 8th are 8 KB */
-		if (j <= 7)
-		{
-		    flash_info[i].start[j] = flashbase + j*0x2000;
+	manuf_code = *(volatile u16 *) CFG_FLASH_BASE;
+	device_code = *(volatile u16 *) (CFG_FLASH_BASE + 2);
+	add_device_code = *(volatile u16 *) (CFG_FLASH_BASE + (3 << 1));
+
+	IDENT_FLASH_ADDR1 = FLASH_CODE1;
+	IDENT_FLASH_ADDR2 = FLASH_CODE2;
+	IDENT_FLASH_ADDR1 = ID_OUT_CODE;
+
+	/* Vendor type */
+	info->flash_id = ATM_MANUFACT & FLASH_VENDMASK;
+	printf ("Atmel: ");
+
+	if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV1614 & FLASH_TYPEMASK)) {
+
+		if ((add_device_code & FLASH_TYPEMASK) ==
+			(ATM_ID_BV1614A & FLASH_TYPEMASK)) {
+			info->flash_id |= ATM_ID_BV1614A & FLASH_TYPEMASK;
+			printf ("AT49BV1614A (16Mbit)\n");
 		}
 
-		/* 9th and 10th are both 32 KB */
-		if ((j == 8) || (j == 9))
-		{
-			flash_info[i].start[j] = flashbase + 0x10000 + (j-8)*0x8000;
-		}
-	    }
-	    else
-	    {
-		flash_info[i].start[j] = flashbase + (j-8)*MAIN_SECT_SIZE;
-	    }
+	} else {				/* AT49BV1614 Flash */
+		info->flash_id |= ATM_ID_BV1614 & FLASH_TYPEMASK;
+		printf ("AT49BV1614 (16Mbit)\n");
 	}
-	size += flash_info[i].size;
-    }
+}
 
-    flash_protect(FLAG_PROTECT_SET,
-		  CFG_FLASH_BASE,
-		  CFG_ENV_ADDR - 1,
-		  &flash_info[0]);
 
-    flash_protect(FLAG_PROTECT_SET,
-		  CFG_ENV_ADDR,
-		  CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
-		  &flash_info[0]);
+ulong flash_init (void)
+{
+	int i, j, k;
+	unsigned int flash_nb_blocks, sector;
+	unsigned int start_address;
+	OrgDef *pOrgDef;
 
-    return size;
+	ulong size = 0;
+
+	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
+		ulong flashbase = 0;
+
+		flash_identification (&flash_info[i]);
+
+		flash_info[i].size = FLASH_BANK_SIZE;
+
+		if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
+			(ATM_ID_BV1614 & FLASH_TYPEMASK)) {
+			flash_info[i].sector_count = CFG_MAX_FLASH_SECT;
+			memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT);
+
+			pOrgDef = OrgAT49BV16x4;
+			flash_nb_blocks = sizeof (OrgAT49BV16x4) / sizeof (OrgDef);
+		} else {			/* AT49BV1614A Flash */
+			flash_info[i].sector_count = CFG_MAX_FLASH_SECT - 1;
+			memset (flash_info[i].protect, 0, CFG_MAX_FLASH_SECT - 1);
+
+			pOrgDef = OrgAT49BV16x4A;
+			flash_nb_blocks = sizeof (OrgAT49BV16x4A) / sizeof (OrgDef);
+		}
+
+		if (i == 0)
+			flashbase = PHYS_FLASH_1;
+		else
+			panic ("configured to many flash banks!\n");
+
+		sector = 0;
+		start_address = flashbase;
+
+		for (j = 0; j < flash_nb_blocks; j++) {
+			for (k = 0; k < pOrgDef[j].sector_number; k++) {
+				flash_info[i].start[sector++] = start_address;
+				start_address += pOrgDef[j].sector_size;
+			}
+		}
+
+		size += flash_info[i].size;
+	}
+
+	/* Protect binary boot image */
+	flash_protect (FLAG_PROTECT_SET,
+		       CFG_FLASH_BASE,
+		       CFG_FLASH_BASE + CFG_BOOT_SIZE - 1, &flash_info[0]);
+
+	/* Protect environment variables */
+	flash_protect (FLAG_PROTECT_SET,
+		       CFG_ENV_ADDR,
+		       CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
+
+	/* Protect U-Boot gzipped image */
+	flash_protect (FLAG_PROTECT_SET,
+		       CFG_U_BOOT_BASE,
+		       CFG_U_BOOT_BASE + CFG_U_BOOT_SIZE - 1, &flash_info[0]);
+
+	return size;
 }
 
 /*-----------------------------------------------------------------------
  */
-void flash_print_info  (flash_info_t *info)
+void flash_print_info (flash_info_t * info)
 {
-    int i;
+	int i;
 
-    switch (info->flash_id & FLASH_VENDMASK)
-    {
-    case (ATM_MANUFACT & FLASH_VENDMASK):
-	printf("Atmel: ");
-	break;
-    default:
-	printf("Unknown Vendor ");
-	break;
-    }
-
-    switch (info->flash_id & FLASH_TYPEMASK)
-    {
-    case (ATM_ID_BV1614 & FLASH_TYPEMASK):
-	printf("AT49BV1614 (16Mbit)\n");
-	break;
-    default:
-	printf("Unknown Chip Type\n");
-	goto Done;
-	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   ");
+	switch (info->flash_id & FLASH_VENDMASK) {
+	case (ATM_MANUFACT & FLASH_VENDMASK):
+		printf ("Atmel: ");
+		break;
+	default:
+		printf ("Unknown Vendor ");
+		break;
 	}
-	printf (" %08lX%s", info->start[i],
-		info->protect[i] ? " (RO)" : "     ");
-    }
-    printf ("\n");
 
-Done:
+	switch (info->flash_id & FLASH_TYPEMASK) {
+	case (ATM_ID_BV1614 & FLASH_TYPEMASK):
+		printf ("AT49BV1614 (16Mbit)\n");
+		break;
+	case (ATM_ID_BV1614A & FLASH_TYPEMASK):
+		printf ("AT49BV1614A (16Mbit)\n");
+		break;
+	default:
+		printf ("Unknown Chip Type\n");
+		goto Done;
+		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");
+
+  Done:
 }
 
 /*-----------------------------------------------------------------------
  */
 
-int	flash_erase (flash_info_t *info, int s_first, int s_last)
+int flash_erase (flash_info_t * info, int s_first, int s_last)
 {
-    ulong result;
-    int iflag, cflag, prot, sect;
-    int rc = ERR_OK;
-    int chip1;
+	ulong result;
+	int iflag, cflag, prot, sect;
+	int rc = ERR_OK;
+	int chip1;
 
-    /* first look for protection bits */
+	/* first look for protection bits */
 
-    if (info->flash_id == FLASH_UNKNOWN)
-	return ERR_UNKNOWN_FLASH_TYPE;
+	if (info->flash_id == FLASH_UNKNOWN)
+		return ERR_UNKNOWN_FLASH_TYPE;
 
-    if ((s_first < 0) || (s_first > s_last)) {
-	return ERR_INVAL;
-    }
-
-    if ((info->flash_id & FLASH_VENDMASK) !=
-	(ATM_MANUFACT & FLASH_VENDMASK)) {
-	return ERR_UNKNOWN_FLASH_VENDOR;
-    }
-
-    prot = 0;
-    for (sect=s_first; sect<=s_last; ++sect) {
-	if (info->protect[sect]) {
-	    prot++;
+	if ((s_first < 0) || (s_first > s_last)) {
+		return ERR_INVAL;
 	}
-    }
-    if (prot)
-	return ERR_PROTECTED;
 
-    /*
-     * Disable interrupts which might cause a timeout
-     * here. Remember that our exception vectors are
-     * at address 0 in the flash, and we don't want a
-     * (ticker) exception to happen while the flash
-     * chip is in programming mode.
-     */
-    cflag = icache_status();
-    icache_disable();
-    iflag = disable_interrupts();
+	if ((info->flash_id & FLASH_VENDMASK) !=
+		(ATM_MANUFACT & FLASH_VENDMASK)) {
+		return ERR_UNKNOWN_FLASH_VENDOR;
+	}
 
-    /* Start erase on unprotected sectors */
-    for (sect = s_first; sect<=s_last && !ctrlc(); sect++)
-    {
-	printf("Erasing sector %2d ... ", sect);
-
-	/* arm simple, non interrupt dependent timer */
-	reset_timer_masked();
-
-	if (info->protect[sect] == 0)
-	{	/* not protected */
-	    volatile u16 *addr = (volatile u16 *)(info->start[sect]);
-
-	    MEM_FLASH_ADDR1 = CMD_UNLOCK1;
-	    MEM_FLASH_ADDR2 = CMD_UNLOCK2;
-	    MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
-
-	    MEM_FLASH_ADDR1 = CMD_UNLOCK1;
-	    MEM_FLASH_ADDR2 = CMD_UNLOCK2;
-	    *addr = CMD_ERASE_CONFIRM;
-
-	    /* wait until flash is ready */
-	    chip1 = 0;
-
-	    do
-	    {
-		result = *addr;
-
-		/* check timeout */
-		if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
-		{
-		    MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
-		    chip1 = TMO;
-		    break;
+	prot = 0;
+	for (sect = s_first; sect <= s_last; ++sect) {
+		if (info->protect[sect]) {
+			prot++;
 		}
-
-		if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE)
-			chip1 = READY;
-
-	    }  while (!chip1);
-
-	    MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
-
-	    if (chip1 == ERR)
-	    {
-		rc = ERR_PROG_ERROR;
-		goto outahere;
-	    }
-	    if (chip1 == TMO)
-	    {
-		rc = ERR_TIMOUT;
-		goto outahere;
-	    }
-
-	    printf("ok.\n");
 	}
-	else /* it was protected */
-	{
-	    printf("protected!\n");
-	}
-    }
+	if (prot)
+		return ERR_PROTECTED;
 
-    if (ctrlc())
-      printf("User Interrupt!\n");
+	/*
+	 * Disable interrupts which might cause a timeout
+	 * here. Remember that our exception vectors are
+	 * at address 0 in the flash, and we don't want a
+	 * (ticker) exception to happen while the flash
+	 * chip is in programming mode.
+	 */
+	cflag = icache_status ();
+	icache_disable ();
+	iflag = disable_interrupts ();
+
+	/* Start erase on unprotected sectors */
+	for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
+		printf ("Erasing sector %2d ... ", sect);
+
+		/* arm simple, non interrupt dependent timer */
+		reset_timer_masked ();
+
+		if (info->protect[sect] == 0) {	/* not protected */
+			volatile u16 *addr = (volatile u16 *) (info->start[sect]);
+
+			MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+			MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+			MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
+
+			MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+			MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+			*addr = CMD_ERASE_CONFIRM;
+
+			/* wait until flash is ready */
+			chip1 = 0;
+
+			do {
+				result = *addr;
+
+				/* check timeout */
+				if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
+					MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
+					chip1 = TMO;
+					break;
+				}
+
+				if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE)
+					chip1 = READY;
+
+			} while (!chip1);
+
+			MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
+
+			if (chip1 == ERR) {
+				rc = ERR_PROG_ERROR;
+				goto outahere;
+			}
+			if (chip1 == TMO) {
+				rc = ERR_TIMOUT;
+				goto outahere;
+			}
+
+			printf ("ok.\n");
+		} else {			/* it was protected */
+			printf ("protected!\n");
+		}
+	}
+
+	if (ctrlc ())
+		printf ("User Interrupt!\n");
 
 outahere:
-    /* allow flash to settle - wait 10 ms */
-    udelay_masked(10000);
+	/* allow flash to settle - wait 10 ms */
+	udelay_masked (10000);
 
-    if (iflag)
-      enable_interrupts();
+	if (iflag)
+		enable_interrupts ();
 
-    if (cflag)
-      icache_enable();
+	if (cflag)
+		icache_enable ();
 
-    return rc;
+	return rc;
 }
 
 /*-----------------------------------------------------------------------
  * Copy memory to flash
  */
 
-volatile static int write_word (flash_info_t *info, ulong dest, ulong data)
+volatile static int write_word (flash_info_t * info, ulong dest,
+								ulong data)
 {
-    volatile u16 *addr = (volatile u16 *)dest;
-    ulong result;
-    int rc = ERR_OK;
-    int cflag, iflag;
-    int chip1;
+	volatile u16 *addr = (volatile u16 *) dest;
+	ulong result;
+	int rc = ERR_OK;
+	int cflag, iflag;
+	int chip1;
 
-    /*
-     * Check if Flash is (sufficiently) erased
-     */
-    result = *addr;
-    if ((result & data) != data)
-        return ERR_NOT_ERASED;
-
-
-    /*
-     * Disable interrupts which might cause a timeout
-     * here. Remember that our exception vectors are
-     * at address 0 in the flash, and we don't want a
-     * (ticker) exception to happen while the flash
-     * chip is in programming mode.
-     */
-    cflag = icache_status();
-    icache_disable();
-    iflag = disable_interrupts();
-
-    MEM_FLASH_ADDR1 = CMD_UNLOCK1;
-    MEM_FLASH_ADDR2 = CMD_UNLOCK2;
-    MEM_FLASH_ADDR1 = CMD_PROGRAM;
-    *addr = data;
-
-    /* arm simple, non interrupt dependent timer */
-    reset_timer_masked();
-
-    /* wait until flash is ready */
-    chip1 = 0;
-    do
-    {
+	/*
+	 * Check if Flash is (sufficiently) erased
+	 */
 	result = *addr;
+	if ((result & data) != data)
+		return ERR_NOT_ERASED;
 
-	/* check timeout */
-	if (get_timer_masked() > CFG_FLASH_ERASE_TOUT)
-	{
-	    chip1 = ERR | TMO;
-	    break;
-	}
-	if (!chip1 && ((result & 0x80) == (data & 0x80)))
-		chip1 = READY;
 
-    }  while (!chip1);
+	/*
+	 * Disable interrupts which might cause a timeout
+	 * here. Remember that our exception vectors are
+	 * at address 0 in the flash, and we don't want a
+	 * (ticker) exception to happen while the flash
+	 * chip is in programming mode.
+	 */
+	cflag = icache_status ();
+	icache_disable ();
+	iflag = disable_interrupts ();
 
-    *addr = CMD_READ_ARRAY;
+	MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+	MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+	MEM_FLASH_ADDR1 = CMD_PROGRAM;
+	*addr = data;
 
-    if (chip1 == ERR || *addr != data)
-        rc = ERR_PROG_ERROR;
+	/* arm simple, non interrupt dependent timer */
+	reset_timer_masked ();
 
-    if (iflag)
-      enable_interrupts();
+	/* wait until flash is ready */
+	chip1 = 0;
+	do {
+		result = *addr;
 
-    if (cflag)
-      icache_enable();
+		/* check timeout */
+		if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
+			chip1 = ERR | TMO;
+			break;
+		}
+		if (!chip1 && ((result & 0x80) == (data & 0x80)))
+			chip1 = READY;
 
-    return rc;
+	} while (!chip1);
+
+	*addr = CMD_READ_ARRAY;
+
+	if (chip1 == ERR || *addr != data)
+		rc = ERR_PROG_ERROR;
+
+	if (iflag)
+		enable_interrupts ();
+
+	if (cflag)
+		icache_enable ();
+
+	return rc;
 }
 
 /*-----------------------------------------------------------------------
  * Copy memory to flash.
  */
 
-int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
 {
-    ulong wp, data;
-    int rc;
+	ulong wp, data;
+	int rc;
 
-    if(addr & 1) {
-      printf("unaligned destination not supported\n");
-      return ERR_ALIGN;
-    };
+	if (addr & 1) {
+		printf ("unaligned destination not supported\n");
+		return ERR_ALIGN;
+	};
 
-    if((int)src & 1) {
-      printf("unaligned source not supported\n");
-      return ERR_ALIGN;
-    };
+	if ((int) src & 1) {
+		printf ("unaligned source not supported\n");
+		return ERR_ALIGN;
+	};
 
-    wp = addr;
+	wp = addr;
 
-    while (cnt >= 2) {
-	data = *((volatile u16*)src);
-	if ((rc = write_word(info, wp, data)) != 0) {
-	    return (rc);
+	while (cnt >= 2) {
+		data = *((volatile u16 *) src);
+		if ((rc = write_word (info, wp, data)) != 0) {
+			return (rc);
+		}
+		src += 2;
+		wp += 2;
+		cnt -= 2;
 	}
-	src += 2;
-	wp  += 2;
-	cnt -= 2;
-    }
 
-    if(cnt == 1) {
-      data =  (*((volatile u8*)src)) | (*((volatile u8*)(wp+1)) << 8);
-	if ((rc = write_word(info, wp, data)) != 0) {
-	    return (rc);
-	}
-	src += 1;
-	wp  += 1;
-	cnt -= 1;
-    };
+	if (cnt == 1) {
+		data = (*((volatile u8 *) src)) | (*((volatile u8 *) (wp + 1)) <<
+										   8);
+		if ((rc = write_word (info, wp, data)) != 0) {
+			return (rc);
+		}
+		src += 1;
+		wp += 1;
+		cnt -= 1;
+	};
 
-    return ERR_OK;
+	return ERR_OK;
 }
diff --git a/board/kup4k/kup4k.c b/board/kup4k/kup4k.c
index b3ede17..7981df3 100644
--- a/board/kup4k/kup4k.c
+++ b/board/kup4k/kup4k.c
@@ -299,12 +299,6 @@
 
 void lcd_logo (bd_t * bd)
 {
-
-
-	volatile immap_t *immap = (immap_t *) CFG_IMMR;
-
-
-
 	FB_INFO_S1D13xxx fb_info;
 	S1D_INDEX s1dReg;
 	S1D_VALUE s1dValue;
@@ -328,8 +322,8 @@
 			 /**/
 /*----------------------------------------------------------------------------- */
 			memctl = &immr->im_memctl;
-/*    memctl->memc_or5 = 0xFFC007F0;    / * 4 MB  17 WS or externel TA */
-/*    memctl->memc_br5 = 0x80000801;    / * Start at 0x80000000 */
+/*	memctl->memc_or5 = 0xFFC007F0;    / * 4 MB  17 WS or externel TA */
+/*	memctl->memc_br5 = 0x80000801;    / * Start at 0x80000000 */
 
 	memctl->memc_or5 = 0xFFC00708;	/* 4 MB  17 WS or externel TA */
 	memctl->memc_br5 = 0x80080801;	/* Start at 0x80080000 */
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index af62bec..8af7c7c 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -56,6 +56,10 @@
 #include <logbuff.h>
 #endif
 
+#ifdef CONFIG_HAS_DATAFLASH
+#include <dataflash.h>
+#endif
+
 /*
  * Some systems (for example LWMON) have very short watchdog periods;
  * we must make sure to split long operations like memmove() or
@@ -138,6 +142,11 @@
 	printf ("## Booting image at %08lx ...\n", addr);
 
 	/* Copy header so we can blank CRC field for re-calculation */
+#ifdef CONFIG_HAS_DATAFLASH
+	if (addr_dataflash(addr)){
+		read_dataflash(addr, sizeof(image_header_t), (char *)&header);
+	} else
+#endif
 	memmove (&header, (char *)addr, sizeof(image_header_t));
 
 	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
@@ -178,6 +187,13 @@
 	data = addr + sizeof(image_header_t);
 	len  = ntohl(hdr->ih_size);
 
+#ifdef CONFIG_HAS_DATAFLASH
+	if (addr_dataflash(addr)){
+		read_dataflash(data, len, (char *)CFG_LOAD_ADDR);
+		data = CFG_LOAD_ADDR;
+	}
+#endif	
+
 	if (verify) {
 		printf ("   Verifying Checksum ... ");
 		if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {
diff --git a/common/cmd_flash.c b/common/cmd_flash.c
index 92faf62..efc89dc 100644
--- a/common/cmd_flash.c
+++ b/common/cmd_flash.c
@@ -29,6 +29,10 @@
 #include <cmd_boot.h>
 #include <flash.h>
 
+#ifdef CONFIG_HAS_DATAFLASH
+#include <dataflash.h>
+#endif
+
 #if (CONFIG_COMMANDS & CFG_CMD_FLASH)
 
 extern flash_info_t flash_info[];	/* info for FLASH chips */
@@ -96,6 +100,10 @@
 {
 	ulong bank;
 
+#ifdef CONFIG_HAS_DATAFLASH
+	dataflash_print_info();
+#endif
+
 	if (argc == 1) {	/* print info for all FLASH banks */
 		for (bank=0; bank <CFG_MAX_FLASH_BANKS; ++bank) {
 			printf ("\nBank # %ld: ", bank+1);
diff --git a/common/cmd_immap.c b/common/cmd_immap.c
index 443335b..3eb5895 100644
--- a/common/cmd_immap.c
+++ b/common/cmd_immap.c
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2000
+ * (C) Copyright 2000-2003
  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  *
  * See file CREDITS for list of people who contributed to this
@@ -150,7 +150,24 @@
 int
 do_carinfo (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
-	unimplemented (cmdtp, flag, argc, argv);
+	volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+#if defined(CONFIG_8xx)
+	volatile car8xx_t *car = &immap->im_clkrst;
+#elif defined(CONFIG_8260)
+	volatile car8260_t *car = &immap->im_clkrst;
+#endif
+
+#if defined(CONFIG_8xx)
+	printf ("SCCR  = %08x\n", car->car_sccr);
+	printf ("PLPRCR= %08x\n", car->car_plprcr);
+	printf ("RSR   = %08x\n", car->car_rsr);
+#elif defined(CONFIG_8260)
+	printf ("SCCR  = %08x\n", car->car_sccr);
+	printf ("SCMR  = %08x\n", car->car_scmr);
+	printf ("RSR   = %08x\n", car->car_rsr);
+	printf ("RMR   = %08x\n", car->car_rmr);
+#endif
 	return 0;
 }
 
@@ -168,7 +185,7 @@
 	int i;
 
 	if (counter % 2)
-	putc('\n');
+		putc('\n');
 	counter = 0;
 
 	for (i = 0; i < 4; i++, data += 79)
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index bbfe958..aca6926 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -33,6 +33,9 @@
 #if (CONFIG_COMMANDS & CFG_CMD_MMC)
 #include <mmc.h>
 #endif
+#ifdef CONFIG_HAS_DATAFLASH
+#include <dataflash.h>
+#endif
 
 #if (CONFIG_COMMANDS & (CFG_CMD_MEMORY | CFG_CMD_PCI | CFG_CMD_I2C\
 			| CMD_CMD_PORTIO))
@@ -131,6 +134,23 @@
 
 		printf("%08lx:", addr);
 		linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
+
+#ifdef CONFIG_HAS_DATAFLASH
+		if (read_dataflash(addr, (linebytes/size)*size, linebuf) != -1){
+
+			for (i=0; i<linebytes; i+= size) {
+				if (size == 4) {
+					printf(" %08x", *uip++);
+				} else if (size == 2) {
+					printf(" %04x", *usp++);
+				} else {
+					printf(" %02x", *ucp++);
+				}
+				addr += size;
+			}
+			
+		} else {	/* addr does not correspond to DataFlash */
+#endif
 		for (i=0; i<linebytes; i+= size) {
 			if (size == 4) {
 				printf(" %08x", (*uip++ = *((uint *)addr)));
@@ -141,6 +161,9 @@
 			}
 			addr += size;
 		}
+#ifdef CONFIG_HAS_DATAFLASH
+		}
+#endif
 		printf("    ");
 		cp = linebuf;
 		for (i=0; i<linebytes; i++) {
@@ -236,6 +259,13 @@
 
 	count = simple_strtoul(argv[3], NULL, 16);
 
+#ifdef CONFIG_HAS_DATAFLASH
+	if (addr_dataflash(addr1) | addr_dataflash(addr2)){
+		printf("Comparison with DataFlash space not supported.\n\r");
+		return 0;
+	}
+#endif
+
 	ngood = 0;
 
 	while (count-- > 0) {
@@ -311,7 +341,11 @@
 
 #ifndef CFG_NO_FLASH
 	/* check if we are copying to Flash */
-	if (addr2info(dest) != NULL) {
+	if ( (addr2info(dest) != NULL)
+#ifdef CONFIG_HAS_DATAFLASH
+	   && (!addr_dataflash(addr))
+#endif
+	   ) {
 		int rc;
 
 		printf ("Copy to Flash... ");
@@ -366,6 +400,35 @@
 	}
 #endif
 
+#ifdef CONFIG_HAS_DATAFLASH
+	/* Check if we are copying from RAM or Flash to DataFlash */
+	if (addr_dataflash(dest) && !addr_dataflash(addr)){
+		int rc;
+
+		printf ("Copy to DataFlash... ");
+
+		rc = write_dataflash (dest, addr, count*size);
+
+		if (rc != 1) {
+			dataflash_perror (rc);
+			return (1);
+		}
+		puts ("done\n");
+		return 0;
+	}
+	
+	/* Check if we are copying from DataFlash to RAM */
+	if (addr_dataflash(addr) && !addr_dataflash(dest) && (addr2info(dest)==NULL) ){
+		read_dataflash(addr, count * size, (char *) dest);
+		return 0;
+	}
+
+	if (addr_dataflash(addr) && addr_dataflash(dest)){
+		printf("Unsupported combination of source/destination.\n\r");
+		return 1;
+	}
+#endif
+
 	while (count-- > 0) {
 		if (size == 4)
 			*((ulong  *)dest) = *((ulong  *)addr);
@@ -805,6 +868,13 @@
 		addr += base_address;
 	}
 
+#ifdef CONFIG_HAS_DATAFLASH
+	if (addr_dataflash(addr)){
+		printf("Can't modify DataFlash in place. Use cp instead.\n\r");
+		return 0;
+	}
+#endif
+
 	/* Print the address, followed by value.  Then accept input for
 	 * the next value.  A non-converted value exits.
 	 */
diff --git a/cpu/at91rm9200/Makefile b/cpu/at91rm9200/Makefile
index 0953c9f..fdf6adb 100644
--- a/cpu/at91rm9200/Makefile
+++ b/cpu/at91rm9200/Makefile
@@ -26,7 +26,8 @@
 LIB	= lib$(CPU).a
 
 START	= start.o
-OBJS	= serial.o interrupts.o cpu.o
+OBJS	= serial.o interrupts.o cpu.o \
+	  at91rm9200_ether.o at45.o
 
 all:	.depend $(START) $(LIB)
 
diff --git a/cpu/at91rm9200/at45.c b/cpu/at91rm9200/at45.c
new file mode 100644
index 0000000..e0057e7
--- /dev/null
+++ b/cpu/at91rm9200/at45.c
@@ -0,0 +1,521 @@
+/* Driver for ATMEL DataFlash support
+ * Author : Hamid Ikdoumi (Atmel)
+ *
+ * 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 <config.h>
+#include <common.h>
+#include <asm/hardware.h>
+
+#ifdef CONFIG_HAS_DATAFLASH
+#include <dataflash.h>
+
+#define SPI_CLK 5000000
+#define AT91C_SPI_PCS0_SERIAL_DATAFLASH		0xE     /* Chip Select 0 : NPCS0 %1110 */
+#define AT91C_SPI_PCS3_DATAFLASH_CARD		0x7     /* Chip Select 3 : NPCS3 %0111 */
+
+void AT91F_SpiInit(void) {
+
+/*-------------------------------------------------------------------*/
+/*	SPI DataFlash Init								*/
+/*-------------------------------------------------------------------*/
+	/* Configure PIOs */
+	AT91C_BASE_PIOA->PIO_ASR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
+				   AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK;
+	AT91C_BASE_PIOA->PIO_PDR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
+				   AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK;
+	/* Enable CLock */
+	AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI;
+
+	/* Reset the SPI */
+	AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
+
+    	/* Configure SPI in Master Mode with No CS selected !!! */
+	AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS;
+
+	/* Configure CS0 and CS3 */
+	*(AT91C_SPI_CSR + 0) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*SPI_CLK)) << 8);
+
+	*(AT91C_SPI_CSR + 3) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*SPI_CLK)) << 8);
+
+}
+
+void AT91F_SpiEnable(int cs) {
+	switch(cs) {
+	case 0:	/* Configure SPI CS0 for Serial DataFlash AT45DBxx */
+		AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
+		AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS0_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS);
+		break;
+	case 3:	/* Configure SPI CS3 for Serial DataFlash Card */
+		/* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard */
+		AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB7;	/* Set in PIO mode */
+		AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB7;	/* Configure in output */
+		/* Clear Output */
+		AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7;
+		/* Configure PCS */
+		AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
+		AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS);
+		break;
+	}
+
+	/* SPI_Enable */
+	AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
+}
+
+/*----------------------------------------------------------------------------*/
+/* \fn    AT91F_SpiWrite						      */
+/* \brief Set the PDC registers for a transfert				      */
+/*----------------------------------------------------------------------------*/
+unsigned int AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc )
+{
+   	unsigned int timeout;
+
+	pDesc->state = BUSY;
+
+   	AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
+
+   	/* Initialize the Transmit and Receive Pointer */
+    	AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ;
+    	AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ;
+
+    	/* Intialize the Transmit and Receive Counters */
+    	AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size;
+    	AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size;
+
+	if ( pDesc->tx_data_size != 0 ) {
+	   	/* Initialize the Next Transmit and Next Receive Pointer */
+	    	AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ;
+		AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ;
+
+		/* Intialize the Next Transmit and Next Receive Counters */
+		AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ;
+	 	AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ;
+   	}
+
+        /* arm simple, non interrupt dependent timer */
+	reset_timer_masked();
+	timeout = 0;
+
+	AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN;
+	while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF) && ((timeout = get_timer_masked() ) < CFG_SPI_WRITE_TOUT));
+   	AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
+   	pDesc->state = IDLE;
+
+	if (timeout >= CFG_SPI_WRITE_TOUT){
+		printf("Error Timeout\n\r");
+		return DATAFLASH_ERROR;
+	}
+
+	return DATAFLASH_OK;
+}
+
+
+/*----------------------------------------------------------------------*/
+/* \fn    AT91F_DataFlashSendCommand					*/
+/* \brief Generic function to send a command to the dataflash		*/
+/*----------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashSendCommand(
+	AT91PS_DataFlash pDataFlash,
+	unsigned char OpCode,
+	unsigned int CmdSize,
+	unsigned int DataflashAddress)
+{
+    unsigned int adr;
+
+	if ( (pDataFlash->pDataFlashDesc->state) != IDLE)
+		return DATAFLASH_BUSY;
+
+	/* process the address to obtain page address and byte address */
+	adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) << pDataFlash->pDevice->page_offset) + (DataflashAddress % (pDataFlash->pDevice->pages_size));
+
+	/* fill the  command  buffer */
+	pDataFlash->pDataFlashDesc->command[0] = OpCode;
+	pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16);
+	pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8);
+	pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ;
+	pDataFlash->pDataFlashDesc->command[4] = 0;
+	pDataFlash->pDataFlashDesc->command[5] = 0;
+	pDataFlash->pDataFlashDesc->command[6] = 0;
+	pDataFlash->pDataFlashDesc->command[7] = 0;
+
+	/* Initialize the SpiData structure for the spi write fuction */
+	pDataFlash->pDataFlashDesc->tx_cmd_pt   =  pDataFlash->pDataFlashDesc->command ;
+	pDataFlash->pDataFlashDesc->tx_cmd_size =  CmdSize ;
+	pDataFlash->pDataFlashDesc->rx_cmd_pt   =  pDataFlash->pDataFlashDesc->command ;
+	pDataFlash->pDataFlashDesc->rx_cmd_size =  CmdSize ;
+
+	/* send the command and read the data */
+	return AT91F_SpiWrite (pDataFlash->pDataFlashDesc);
+}
+
+
+/*----------------------------------------------------------------------*/
+/* \fn    AT91F_DataFlashGetStatus					*/
+/* \brief Read the status register of the dataflash			*/
+/*----------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
+{
+	AT91S_DataFlashStatus status;
+
+	/* if a transfert is in progress ==> return 0 */
+	if( (pDesc->state) != IDLE)
+		return DATAFLASH_BUSY;
+
+	/* first send the read status command (D7H) */
+	pDesc->command[0] = DB_STATUS;
+	pDesc->command[1] = 0;
+
+	pDesc->DataFlash_state  = GET_STATUS;
+    	pDesc->tx_data_size 	= 0 ;	/* Transmit the command and receive response */
+    	pDesc->tx_cmd_pt 		= pDesc->command ;
+    	pDesc->rx_cmd_pt 		= pDesc->command ;
+    	pDesc->rx_cmd_size 		= 2 ;
+    	pDesc->tx_cmd_size 		= 2 ;
+    	status = AT91F_SpiWrite (pDesc);
+
+	pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);
+
+	return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/* \fn    AT91F_DataFlashWaitReady					*/
+/* \brief wait for dataflash ready (bit7 of the status register == 1)	*/
+/*----------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc pDataFlashDesc, unsigned int timeout)
+{
+	pDataFlashDesc->DataFlash_state = IDLE;
+
+	do {
+		AT91F_DataFlashGetStatus(pDataFlashDesc);
+		timeout--;
+	}
+	while( ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout > 0) );
+
+	if((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
+		return DATAFLASH_ERROR;
+
+	return DATAFLASH_OK;
+}
+
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataFlashContinuousRead 				*/
+/* Object              : Continuous stream Read 				*/
+/* Input Parameters    : DataFlash Service					*/
+/*						: <src> = dataflash address	*/
+/*                     : <*dataBuffer> = data buffer pointer			*/
+/*                     : <sizeToRead> = data buffer size			*/
+/* Return value		: State of the dataflash				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashContinuousRead (
+ 	AT91PS_DataFlash pDataFlash,
+	int src,
+	unsigned char *dataBuffer,
+	int sizeToRead )
+{
+	/* Test the size to read in the device */
+	if ( (src + sizeToRead) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
+		return DATAFLASH_MEMORY_OVERFLOW;
+
+	pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
+	pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
+	pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
+	pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
+
+	/* Send the command to the dataflash */
+	return(AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src));
+}
+
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataFlashPagePgmBuf				*/
+/* Object              : Main memory page program through buffer 1 or buffer 2	*/
+/* Input Parameters    : DataFlash Service					*/
+/*						: <*src> = Source buffer	*/
+/*                     : <dest> = dataflash destination address			*/
+/*                     : <SizeToWrite> = data buffer size			*/
+/* Return value		: State of the dataflash				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf(
+	AT91PS_DataFlash pDataFlash,
+	unsigned char *src,
+	unsigned int dest,
+	unsigned int SizeToWrite)
+{
+	pDataFlash->pDataFlashDesc->tx_data_pt = src ;
+	pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
+	pDataFlash->pDataFlashDesc->rx_data_pt = src;
+	pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
+
+	/* Send the command to the dataflash */
+	return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_PGM_BUF1, 4, dest));
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_MainMemoryToBufferTransfert			*/
+/* Object              : Read a page in the SRAM Buffer 1 or 2			*/
+/* Input Parameters    : DataFlash Service					*/
+/*                     : Page concerned						*/
+/*                     : 							*/
+/* Return value		: State of the dataflash				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
+	AT91PS_DataFlash pDataFlash,
+	unsigned char BufferCommand,
+	unsigned int page)
+{
+	/* Test if the buffer command is legal */
+	if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && (BufferCommand != DB_PAGE_2_BUF2_TRF))
+		return DATAFLASH_BAD_COMMAND;
+
+	/* no data to transmit or receive */
+    	pDataFlash->pDataFlashDesc->tx_data_size = 0;
+
+	return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, page*pDataFlash->pDevice->pages_size));
+}
+
+
+
+/*----------------------------------------------------------------------------- */
+/* Function Name       : AT91F_DataFlashWriteBuffer				*/
+/* Object              : Write data to the internal sram buffer 1 or 2		*/
+/* Input Parameters    : DataFlash Service					*/
+/*			: <BufferCommand> = command to write buffer1 or buffer2	*/
+/*                     : <*dataBuffer> = data buffer to write			*/
+/*                     : <bufferAddress> = address in the internal buffer	*/
+/*                     : <SizeToWrite> = data buffer size			*/
+/* Return value		: State of the dataflash				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer (
+	AT91PS_DataFlash pDataFlash,
+	unsigned char BufferCommand,
+	unsigned char *dataBuffer,
+	unsigned int bufferAddress,
+	int SizeToWrite )
+{
+	/* Test if the buffer command is legal */
+	if ((BufferCommand != DB_BUF1_WRITE) && (BufferCommand != DB_BUF2_WRITE))
+		return DATAFLASH_BAD_COMMAND;
+
+	/* buffer address must be lower than page size */
+	if (bufferAddress > pDataFlash->pDevice->pages_size)
+		return DATAFLASH_BAD_ADDRESS;
+
+	if ( (pDataFlash->pDataFlashDesc->state)  != IDLE)
+		return DATAFLASH_BUSY;
+
+    	/* Send first Write Command */
+    	pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
+	pDataFlash->pDataFlashDesc->command[1] = 0;
+    	pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress &  pDataFlash->pDevice->byte_mask)) >> 8) ;
+    	pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress  & 0x00FF) ;
+
+
+    	pDataFlash->pDataFlashDesc->tx_cmd_pt 	 = pDataFlash->pDataFlashDesc->command ;
+    	pDataFlash->pDataFlashDesc->tx_cmd_size = 4 ;
+    	pDataFlash->pDataFlashDesc->rx_cmd_pt 	 = pDataFlash->pDataFlashDesc->command ;
+    	pDataFlash->pDataFlashDesc->rx_cmd_size = 4 ;
+
+    	pDataFlash->pDataFlashDesc->rx_data_pt 	= dataBuffer ;
+    	pDataFlash->pDataFlashDesc->tx_data_pt 	= dataBuffer ;
+    	pDataFlash->pDataFlashDesc->rx_data_size 	= SizeToWrite ;
+    	pDataFlash->pDataFlashDesc->tx_data_size 	= SizeToWrite ;
+
+    	return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_WriteBufferToMain				*/
+/* Object              : Write buffer to the main memory			*/
+/* Input Parameters    : DataFlash Service					*/
+/*		: <BufferCommand> = command to send to buffer1 or buffer2	*/
+/*                     : <dest> = main memory address				*/
+/* Return value		: State of the dataflash				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_WriteBufferToMain (
+	AT91PS_DataFlash pDataFlash,
+	unsigned char BufferCommand,
+	unsigned int dest )
+{
+	/* Test if the buffer command is correct */
+	if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
+	    (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
+	    (BufferCommand != DB_BUF2_PAGE_PGM) &&
+	    (BufferCommand != DB_BUF2_PAGE_ERASE_PGM) )
+		return DATAFLASH_BAD_COMMAND;
+
+	/* no data to transmit or receive */
+	pDataFlash->pDataFlashDesc->tx_data_size = 0;
+
+	/* Send the command to the dataflash */
+	return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, dest));
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_PartialPageWrite					*/
+/* Object              : Erase partielly a page					*/
+/* Input Parameters    : <page> = page number					*/
+/*			: <AdrInpage> = adr to begin the fading			*/
+/*                     : <length> = Number of bytes to erase			*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_PartialPageWrite (
+	AT91PS_DataFlash pDataFlash,
+	unsigned char *src,
+	unsigned int dest,
+	unsigned int size)
+{
+	unsigned int page;
+	unsigned int AdrInPage;
+
+	page = dest / (pDataFlash->pDevice->pages_size);
+	AdrInPage = dest % (pDataFlash->pDevice->pages_size);
+
+	/* Read the contents of the page in the Sram Buffer */
+	AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
+	AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+	/*Update the SRAM buffer */
+	AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size);
+	AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+
+	/* Rewrite the modified Sram Buffer in the main memory */
+	return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM, (page*pDataFlash->pDevice->pages_size)));
+}
+
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataFlashWrite_Overloaded			*/
+/* Object              :							*/
+/* Input Parameters    : <*src> = Source buffer					*/
+/*                     : <dest> = dataflash adress				*/
+/*                     : <size> = data buffer size				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashWrite(
+	AT91PS_DataFlash pDataFlash,
+	unsigned char *src,
+	int dest,
+	int size )
+{
+	unsigned int length;
+
+	AT91F_SpiEnable(pDataFlash->pDevice->cs);
+
+    	if ( (dest + size) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
+		return DATAFLASH_MEMORY_OVERFLOW;
+
+    	/* If destination does not fit a page start address */
+    	if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size)))  != 0 ) {
+		length = pDataFlash->pDevice->pages_size - (dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));
+
+		if (size < length)
+			length = size;
+
+		if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length))
+			return DATAFLASH_ERROR;
+
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+
+		/* Update size, source and destination pointers */
+        	size -= length;
+        	dest += length;
+        	src += length;
+    	}
+
+    	while (( size - pDataFlash->pDevice->pages_size ) >= 0 ) {
+		/* program dataflash page */
+		if(!AT91F_DataFlashPagePgmBuf(pDataFlash, src, dest, pDataFlash->pDevice->pages_size ))
+			return DATAFLASH_ERROR;
+
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+
+		/* Update size, source and destination pointers */
+        	size -= pDataFlash->pDevice->pages_size ;
+        	dest += pDataFlash->pDevice->pages_size ;
+        	src  += pDataFlash->pDevice->pages_size ;
+    	}
+
+    	/* If still some bytes to read */
+    	if ( size > 0 ) {
+		/* program dataflash page */
+		if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) )
+			return DATAFLASH_ERROR;
+
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+	}
+    	return DATAFLASH_OK;
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataFlashRead 					*/
+/* Object              : Read a block in dataflash				*/
+/* Input Parameters    : 							*/
+/* Return value		: 							*/
+/*------------------------------------------------------------------------------*/
+int AT91F_DataFlashRead(
+	AT91PS_DataFlash pDataFlash,
+	unsigned long addr,
+	unsigned long size,
+	char *buffer)
+{
+	unsigned long SizeToRead;
+
+	AT91F_SpiEnable(pDataFlash->pDevice->cs);
+
+	if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK)
+		return -1;
+
+	while (size) {
+		SizeToRead = (size < 0x8000)? size:0x8000;
+
+		if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK)
+			return -1;
+
+		if (AT91F_DataFlashContinuousRead (pDataFlash, addr, buffer, SizeToRead) != DATAFLASH_OK)
+			return -1;
+
+		size -= SizeToRead;
+		addr += SizeToRead;
+		buffer += SizeToRead;
+	}
+
+   	return DATAFLASH_OK;
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataflashProbe 					*/
+/* Object              : 							*/
+/* Input Parameters    : 							*/
+/* Return value	       : Dataflash status register				*/
+/*------------------------------------------------------------------------------*/
+int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
+{
+	AT91F_SpiEnable(cs);
+   	AT91F_DataFlashGetStatus(pDesc);
+   	return((pDesc->command[1] == 0xFF)? 0: pDesc->command[1] & 0x3C);
+}
+
+#endif
diff --git a/cpu/at91rm9200/at91rm9200_ether.c b/cpu/at91rm9200/at91rm9200_ether.c
new file mode 100644
index 0000000..6e44150
--- /dev/null
+++ b/cpu/at91rm9200/at91rm9200_ether.c
@@ -0,0 +1,468 @@
+/*
+ * (C) Copyright 2003
+ * Author : Hamid Ikdoumi (Atmel)
+ *
+ * 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 <at91rm9200_net.h>
+#include <net.h>
+
+/* ----- Ethernet Buffer definitions ----- */
+
+typedef struct {
+	unsigned long addr, size;
+} rbf_t;
+
+#define RBF_ADDR      0xfffffffc
+#define RBF_OWNER     (1<<0)
+#define RBF_WRAP      (1<<1)
+#define RBF_BROADCAST (1<<31)
+#define RBF_MULTICAST (1<<30)
+#define RBF_UNICAST   (1<<29)
+#define RBF_EXTERNAL  (1<<28)
+#define RBF_UNKOWN    (1<<27)
+#define RBF_SIZE      0x07ff
+#define RBF_LOCAL4    (1<<26)
+#define RBF_LOCAL3    (1<<25)
+#define RBF_LOCAL2    (1<<24)
+#define RBF_LOCAL1    (1<<23)
+
+/* Emac Buffers in last 512KBytes of SDRAM*/
+/* Be careful, buffer size is limited to 512KBytes !!! */
+#define RBF_FRAMEMAX 100
+/*#define RBF_FRAMEMEM 0x200000 */
+#define RBF_FRAMEMEM 0x21F80000
+#define RBF_FRAMELEN 0x600
+
+#define RBF_FRAMEBTD RBF_FRAMEMEM
+#define RBF_FRAMEBUF (RBF_FRAMEMEM + RBF_FRAMEMAX*sizeof(rbf_t))
+
+
+#ifdef CONFIG_DRIVER_ETHER
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+/* structure to interface the PHY */
+AT91S_PhyOps AT91S_Dm9161Ops;
+AT91PS_PhyOps pPhyOps;
+
+AT91PS_EMAC p_mac;
+
+/*************************** Phy layer functions ************************/
+/** functions to interface the DAVICOM 10/100Mbps ethernet phy **********/
+
+/*
+ * Name: 
+ *	dm9161_IsPhyConnected
+ * Description: 
+ *	Reads the 2 PHY ID registers
+ * Arguments: 
+ *	p_mac - pointer to AT91S_EMAC struct
+ * Return value: 
+ *	TRUE - if id read successfully
+ *	FALSE- if error 
+ */
+static unsigned int dm9161_IsPhyConnected (AT91PS_EMAC p_mac)
+{
+	unsigned short Id1, Id2;
+
+	at91rm9200_EmacEnableMDIO (p_mac);
+	at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID1, &Id1);
+	at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID2, &Id2);
+	at91rm9200_EmacDisableMDIO (p_mac);
+
+	if ((Id1 == (DM9161_PHYID1_OUI >> 6)) &&
+		((Id2 >> 10) == (DM9161_PHYID1_OUI & DM9161_LSB_MASK)))
+		return TRUE;
+
+	return FALSE;
+}
+
+/*
+ * Name: 
+ *	dm9161_GetLinkSpeed
+ * Description: 
+ *	Link parallel detection status of MAC is checked and set in the 
+ *	MAC configuration registers
+ * Arguments: 
+ *	p_mac - pointer to MAC 
+ * Return value: 
+ *	TRUE - if link status set succesfully
+ *	FALSE - if link status not set
+ */
+static UCHAR dm9161_GetLinkSpeed (AT91PS_EMAC p_mac)
+{
+	unsigned short stat1, stat2;
+
+	if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &stat1))
+		return FALSE;
+
+	if (!(stat1 & DM9161_LINK_STATUS))	/* link status up? */
+		return FALSE;
+
+	if (!at91rm9200_EmacReadPhy (p_mac, DM9161_DSCSR, &stat2))
+		return FALSE;
+
+	if ((stat1 & DM9161_100BASE_TX_FD) && (stat2 & DM9161_100FDX)) {
+		/*set Emac for 100BaseTX and Full Duplex  */
+		p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
+		return TRUE;
+	}
+
+	if ((stat1 & DM9161_10BASE_T_FD) && (stat2 & DM9161_10FDX)) {
+		/*set MII for 10BaseT and Full Duplex  */
+		p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+				~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+				| AT91C_EMAC_FD;
+		return TRUE;
+	}
+
+	if ((stat1 & DM9161_100BASE_T4_HD) && (stat2 & DM9161_100HDX)) {
+		/*set MII for 100BaseTX and Half Duplex  */
+		p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+				~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+				| AT91C_EMAC_SPD;
+		return TRUE;
+	}
+
+	if ((stat1 & DM9161_10BASE_T_HD) && (stat2 & DM9161_10HDX)) {
+		/*set MII for 10BaseT and Half Duplex  */
+		p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
+/*
+ * Name: 
+ *	dm9161_InitPhy
+ * Description: 
+ *	MAC starts checking its link by using parallel detection and 
+ *	Autonegotiation and the same is set in the MAC configuration registers
+ * Arguments: 
+ *	p_mac - pointer to struct AT91S_EMAC
+ * Return value: 
+ *	TRUE - if link status set succesfully
+ *	FALSE - if link status not set
+ */
+static UCHAR dm9161_InitPhy (AT91PS_EMAC p_mac)
+{
+	UCHAR ret = TRUE;
+	unsigned short IntValue;
+
+	at91rm9200_EmacEnableMDIO (p_mac);
+
+	if (!dm9161_GetLinkSpeed (p_mac)) {
+		/* Try another time */
+		ret = dm9161_GetLinkSpeed (p_mac);
+	}
+
+	/* Disable PHY Interrupts */
+	at91rm9200_EmacReadPhy (p_mac, DM9161_MDINTR, &IntValue);
+	/* clear FDX, SPD, Link, INTR masks */
+	IntValue &= ~(DM9161_FDX_MASK | DM9161_SPD_MASK |
+		      DM9161_LINK_MASK | DM9161_INTR_MASK);
+	at91rm9200_EmacWritePhy (p_mac, DM9161_MDINTR, &IntValue);
+	at91rm9200_EmacDisableMDIO (p_mac);
+
+	return (ret);
+}
+
+
+/*
+ * Name: 
+ *	dm9161_AutoNegotiate
+ * Description: 
+ *	MAC Autonegotiates with the partner status of same is set in the 
+ *	MAC configuration registers
+ * Arguments: 
+ *	dev - pointer to struct net_device
+ * Return value: 
+ *	TRUE - if link status set successfully
+ *	FALSE - if link status not set
+ */
+static UCHAR dm9161_AutoNegotiate (AT91PS_EMAC p_mac, int *status)
+{
+	unsigned short value;
+	unsigned short PhyAnar;
+	unsigned short PhyAnalpar;
+
+	/* Set dm9161 control register */
+	if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value))
+		return FALSE;
+	value &= ~DM9161_AUTONEG;	/* remove autonegotiation enable */
+	value |= DM9161_ISOLATE;	/* Electrically isolate PHY */
+	if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
+		return FALSE;
+
+	/* Set the Auto_negotiation Advertisement Register */
+	/* MII advertising for Next page, 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */
+	PhyAnar = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX |
+		  DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3;
+	if (!at91rm9200_EmacWritePhy (p_mac, DM9161_ANAR, &PhyAnar))
+		return FALSE;
+
+	/* Read the Control Register     */
+	if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value))
+		return FALSE;
+
+	value |= DM9161_SPEED_SELECT | DM9161_AUTONEG | DM9161_DUPLEX_MODE;
+	if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
+		return FALSE;
+	/* Restart Auto_negotiation  */
+	value |= DM9161_RESTART_AUTONEG;
+	if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
+		return FALSE;
+
+	/*check AutoNegotiate complete */
+	udelay (10000);
+	at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &value);
+	if (!(value & DM9161_AUTONEG_COMP))
+		return FALSE;
+
+	/* Get the AutoNeg Link partner base page */
+	if (!at91rm9200_EmacReadPhy (p_mac, DM9161_ANLPAR, &PhyAnalpar))
+		return FALSE;
+
+	if ((PhyAnar & DM9161_TX_FDX) && (PhyAnalpar & DM9161_TX_FDX)) {
+		/*set MII for 100BaseTX and Full Duplex  */
+		p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
+		return TRUE;
+	}
+
+	if ((PhyAnar & DM9161_10_FDX) && (PhyAnalpar & DM9161_10_FDX)) {
+		/*set MII for 10BaseT and Full Duplex  */
+		p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+				~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+				| AT91C_EMAC_FD;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
+
+
+/*********** EMAC Phy layer Management functions *************************/
+/*
+ * Name: 
+ *	at91rm9200_EmacEnableMDIO
+ * Description: 
+ *	Enables the MDIO bit in MAC control register
+ * Arguments: 
+ *	p_mac - pointer to struct AT91S_EMAC
+ * Return value: 
+ *	none
+ */
+static void at91rm9200_EmacEnableMDIO (AT91PS_EMAC p_mac)
+{
+	/* Mac CTRL reg set for MDIO enable */
+	p_mac->EMAC_CTL |= AT91C_EMAC_MPE;	/* Management port enable */
+}
+
+/*
+ * Name: 
+ *	at91rm9200_EmacDisableMDIO
+ * Description: 
+ *	Disables the MDIO bit in MAC control register
+ * Arguments: 
+ *	p_mac - pointer to struct AT91S_EMAC
+ * Return value: 
+ *	none
+ */
+static void at91rm9200_EmacDisableMDIO (AT91PS_EMAC p_mac)
+{
+	/* Mac CTRL reg set for MDIO disable */
+	p_mac->EMAC_CTL &= ~AT91C_EMAC_MPE;	/* Management port disable */
+}
+
+
+/*
+ * Name: 
+ *	at91rm9200_EmacReadPhy
+ * Description: 
+ *	Reads data from the PHY register
+ * Arguments: 
+ *	dev - pointer to struct net_device
+ *	RegisterAddress - unsigned char
+ * 	pInput - pointer to value read from register 
+ * Return value: 
+ *	TRUE - if data read successfully
+ */
+static UCHAR at91rm9200_EmacReadPhy (AT91PS_EMAC p_mac,
+				     unsigned char RegisterAddress,
+				     unsigned short *pInput)
+{
+	p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) |
+			  (AT91C_EMAC_CODE_802_3) | (AT91C_EMAC_RW_R) |
+			  (RegisterAddress << 18);
+
+	udelay (10000);
+
+	*pInput = (unsigned short) p_mac->EMAC_MAN;
+
+	return TRUE;
+}
+
+
+/*
+ * Name: 
+ *	at91rm9200_EmacWritePhy
+ * Description: 
+ *	Writes data to the PHY register
+ * Arguments: 
+ *	dev - pointer to struct net_device
+ *	RegisterAddress - unsigned char
+ * 	pOutput - pointer to value to be written in the register 
+ * Return value: 
+ *	TRUE - if data read successfully
+ */
+static UCHAR at91rm9200_EmacWritePhy (AT91PS_EMAC p_mac,
+									  unsigned char RegisterAddress,
+									  unsigned short *pOutput)
+{
+	p_mac->EMAC_MAN = (AT91C_EMAC_HIGH & ~AT91C_EMAC_LOW) |
+			AT91C_EMAC_CODE_802_3 | AT91C_EMAC_RW_W |
+			(RegisterAddress << 18);
+
+	udelay (10000);
+
+	return TRUE;
+}
+
+/*
+ * Name: 
+ *	at91rm92000_GetPhyInterface
+ * Description: 
+ *	Initialise the interface functions to the PHY 
+ * Arguments: 
+ *	None
+ * Return value: 
+ *	None
+ */
+void at91rm92000_GetPhyInterface (void)
+{
+	AT91S_Dm9161Ops.Init = dm9161_InitPhy;
+	AT91S_Dm9161Ops.IsPhyConnected = dm9161_IsPhyConnected;
+	AT91S_Dm9161Ops.GetLinkSpeed = dm9161_GetLinkSpeed;
+	AT91S_Dm9161Ops.AutoNegotiate = dm9161_AutoNegotiate;
+
+	pPhyOps = (AT91PS_PhyOps) & AT91S_Dm9161Ops;
+}
+
+
+rbf_t *rbfdt;
+rbf_t *rbfp;
+
+int eth_init (bd_t * bd)
+{
+	int ret;
+	int i;
+
+	p_mac = AT91C_BASE_EMAC;
+
+	*AT91C_PIOA_PDR = AT91C_PA16_EMDIO | AT91C_PA15_EMDC | AT91C_PA14_ERXER | AT91C_PA13_ERX1 | AT91C_PA12_ERX0 | AT91C_PA11_ECRS_ECRSDV | AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN | AT91C_PA7_ETXCK_EREFCK;	/* PIO Disable Register */
+
+	*AT91C_PIOB_PDR = AT91C_PB25_EF100 |
+			AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV |
+			AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER |
+			AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
+
+	*AT91C_PIOB_BSR = AT91C_PB25_EF100 | AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 | AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2;	/* Select B Register */
+
+	*AT91C_PMC_PCER = 1 << AT91C_ID_EMAC;	/* Peripheral Clock Enable Register */
+
+	p_mac->EMAC_CFG |= AT91C_EMAC_CSR;	/* Clear statistics */
+
+	/* Init Ehternet buffers */
+	rbfdt = (rbf_t *) RBF_FRAMEBTD;
+	for (i = 0; i < RBF_FRAMEMAX; i++) {
+		rbfdt[i].addr = RBF_FRAMEBUF + RBF_FRAMELEN * i;
+		rbfdt[i].size = 0;
+	}
+	rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP;
+	rbfp = &rbfdt[0];
+
+	at91rm92000_GetPhyInterface ();
+
+	if (!pPhyOps->IsPhyConnected (p_mac))
+		printf ("PHY not connected!!\n\r");
+
+	/* MII management start from here */
+	if (!(p_mac->EMAC_SR & AT91C_EMAC_LINK)) {
+		if (!(ret = pPhyOps->Init (p_mac))) {
+			printf ("MAC: error during MII initialization\n");
+			return 0;
+		}
+	} else {
+		printf ("No link\n\r");
+		return 0;
+	}
+
+	p_mac->EMAC_SA2L = (bd->bi_enetaddr[3] << 24) | (bd->bi_enetaddr[2] << 16)
+			 | (bd->bi_enetaddr[1] << 8) | (bd->bi_enetaddr[0]);
+	p_mac->EMAC_SA2H = (bd->bi_enetaddr[5] << 8) | (bd->bi_enetaddr[4]);
+
+	p_mac->EMAC_RBQP = (long) (&rbfdt[0]);
+	p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
+	p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC | AT91C_EMAC_RMII)
+			& ~AT91C_EMAC_CLK;
+	p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE;
+
+	return 0;
+}
+
+int eth_send (volatile void *packet, int length)
+{
+	while (!(p_mac->EMAC_TSR & AT91C_EMAC_BNQ));
+	p_mac->EMAC_TAR = (long) packet;
+	p_mac->EMAC_TCR = length;
+	while (p_mac->EMAC_TCR & 0x7ff);
+	p_mac->EMAC_TSR |= AT91C_EMAC_COMP;
+	return 0;
+}
+
+int eth_rx (void)
+{
+	int size;
+
+	if (!(rbfp->addr & RBF_OWNER))
+		return 0;
+
+	size = rbfp->size & RBF_SIZE;
+	NetReceive ((volatile uchar *) (rbfp->addr & RBF_ADDR), size);
+
+	rbfp->addr &= ~RBF_OWNER;
+	if (rbfp->addr & RBF_WRAP)
+		rbfp = &rbfdt[0];
+	else
+		rbfp++;
+
+	p_mac->EMAC_RSR |= AT91C_EMAC_REC;
+
+	return size;
+}
+
+void eth_halt (void)
+{
+};
+#endif	/* CONFIG_COMMANDS & CFG_CMD_NET */
+#endif	/* CONFIG_DRIVER_ETHER */
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index 6736b73..c6a9eda 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -716,7 +716,7 @@
 #endif
 
 /* Machine check */
-	STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
+	CRIT_EXCEPTION(0x200, MachineCheck, MachineCheckException)
 
 /* Data Storage exception. */
 	STD_EXCEPTION(0x300, DataStorage, UnknownException)
diff --git a/drivers/Makefile b/drivers/Makefile
index c1fa419..50fc75a 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -27,9 +27,9 @@
 
 LIB	= libdrivers.a
 
-OBJS	= 3c589.o 5701rls.o ali512x.o at91rm9200_ether.o \
+OBJS	= 3c589.o 5701rls.o ali512x.o \
 	  bcm570x.o bcm570x_autoneg.o cfb_console.o \
-	  cs8900.o ct69000.o dc2114x.o          \
+	  cs8900.o ct69000.o dataflash.o dc2114x.o          \
 	  e1000.o eepro100.o \
 	  i8042.o i82365.o inca-ip_sw.o \
 	  lan91c96.o             natsemi.o \
@@ -41,7 +41,7 @@
 	  ti_pci1410a.o tigon3.o w83c553f.o
 
 ## Disabled for now:
-##	  cs8900.o ct69000.o dc2114x.o ds1722.o \
+##	  cs8900.o ct69000.o dataflash.o dc2114x.o ds1722.o \
 ##	  lan91c96.o mw_eeprom.o natsemi.o \
 ##	  smc91111.o smiLynxEM.o spi_eeprom.o sym53c8xx.o \
 ##
diff --git a/drivers/at91rm9200_ether.c b/drivers/at91rm9200_ether.c
deleted file mode 100644
index f92008e..0000000
--- a/drivers/at91rm9200_ether.c
+++ /dev/null
@@ -1,251 +0,0 @@
-
-#include <common.h>
-#include <command.h>
-#include <asm/io.h>
-#include <net.h>
-
-/* ----- Ethernet Buffer definitions ----- */
-
-typedef struct {
-  unsigned long addr,size;
-} rbf_t;
-
-#define RBF_ADDR      0xfffffffc
-#define RBF_OWNER     (1<<0)
-#define RBF_WRAP      (1<<1)
-#define RBF_BROADCAST (1<<31)
-#define RBF_MULTICAST (1<<30)
-#define RBF_UNICAST   (1<<29)
-#define RBF_EXTERNAL  (1<<28)
-#define RBF_UNKOWN    (1<<27)
-#define RBF_SIZE      0x07ff
-#define RBF_LOCAL4    (1<<26)
-#define RBF_LOCAL3    (1<<25)
-#define RBF_LOCAL2    (1<<24)
-#define RBF_LOCAL1    (1<<23)
-
-#define RBF_FRAMEMAX 10
-#define RBF_FRAMEMEM 0x200000
-#define RBF_FRAMELEN 0x600
-
-#define RBF_FRAMEBTD RBF_FRAMEMEM
-#define RBF_FRAMEBUF (RBF_FRAMEMEM + RBF_FRAMEMAX*sizeof(rbf_t))
-
-/* stolen from mii.h */
-/* Generic MII registers. */
-
-#define MII_BMCR            0x00        /* Basic mode control register */
-#define MII_BMSR            0x01        /* Basic mode status register  */
-#define BMSR_JCD                0x0002  /* Jabber detected             */
-#define BMSR_LSTATUS            0x0004  /* Link status                 */
-#define BMSR_10HALF             0x0800  /* Can do 10mbps, half-duplex  */
-#define BMSR_100FULL            0x4000  /* Can do 100mbps, full-duplex */
-#define BMSR_10FULL             0x1000  /* Can do 10mbps, full-duplex  */
-#define BMSR_100HALF            0x2000  /* Can do 100mbps, half-duplex */
-
-#define MII_STS2_REG	17  /* Davicom specific */
-#define MII_MDINTR_REG	21  /* Davicom specific */
-
-#ifdef CONFIG_DRIVER_ETHER
-
-#if (CONFIG_COMMANDS & CFG_CMD_NET)
-
-AT91PS_EMAC p_mac;
-
-int MII_ReadPhy(unsigned char addr, unsigned short *ret)
-  {
-
-  p_mac->EMAC_MAN = 0x60020000 | (addr << 18);
-  udelay(10000);
-  *ret = (unsigned short)p_mac->EMAC_MAN;
-  return 1;
-  }
-
-
-int MII_GetLinkSpeed(void)
-  {
-  unsigned short stat1, stat2;
-  int ret;
-
-  if (!(ret = MII_ReadPhy(MII_BMSR, &stat1)))
-    return 0;
-
-  if (stat1 & BMSR_JCD)
-    {
-#ifdef DEBUG
-    printf("MII: jabber condition detected\n");
-#endif      /*jabber detected re-read the register*/
-    }
-  if (!(ret = MII_ReadPhy(MII_BMSR, &stat1)))
-    return 0;
-  if (!(stat1 & BMSR_LSTATUS))  /* link status up? */
-    {
-    printf("MII: no Link\n");
-    return 0;
-    }
-
-  if (!(ret = MII_ReadPhy(MII_STS2_REG, &stat2)))
-    return 0;
-
-  if ((stat1 & BMSR_100FULL) && (stat2 & 0x8000) )
-    {
-    /* set MII for 100BaseTX and Full Duplex */
-    p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
-#ifdef DEBUG
-    printf("MII: 100BaseTX and Full Duplex detected\n");
-#endif
-    return 1;
-    }
-
-  else
-    if ((stat1 & BMSR_10FULL) && (stat2 & 0x2000))
-      {
-      /* set MII for 10BaseT and Full Duplex */
-      p_mac->EMAC_CFG = (p_mac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD));
-#ifdef DEBUG
-        printf("MII: 10BaseT and Full Duplex detected\n");
-#endif
-      return 1;
-      }
-    else
-      if ((stat1 & BMSR_100HALF) && (stat2 & 0x4000))
-        {
-        /* set MII for 100BaseTX and Half Duplex */
-        p_mac->EMAC_CFG = (p_mac->EMAC_CFG & ~(AT91C_EMAC_SPD | AT91C_EMAC_FD));
-#ifdef DEBUG
-          printf("MII: 100BaseTX and Hall Duplex detected\n");
-#endif
-        return 1;
-        }
-      else
-        if ((stat1 & BMSR_10HALF) && (stat2 & 0x1000))
-          {
-          /*set MII for 10BaseT and Half Duplex */
-          p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
-#ifdef DEBUG
-          printf("MII: 10BaseT and Hall Duplex detected\n");
-#endif
-          return 1;
-          }
-
-  return 0;
-  }
-
-
-int MDIO_StartupPhy(void)
-  {
-  int ret;
-
-  if(p_mac->EMAC_SR & AT91C_EMAC_LINK)
-    {
-    printf("MDIO_StartupPhy: no link\n");
-    return 0;
-    };
-
-  p_mac->EMAC_CTL |= AT91C_EMAC_MPE;
-
-  ret = MII_GetLinkSpeed();
-  if (ret == 0)
-    {
-    printf("MDIO_StartupPhy: MII_GetLinkSpeed failed\n");
-    ret = 0;
-    }
-  else
-    {
-    ret = 1;
-    }
-
-  p_mac->EMAC_CTL &= ~AT91C_EMAC_MPE;
-  return ret;
-
-  }
-
-
-rbf_t* rbfdt;
-rbf_t* rbfp;
-
-int eth_init( bd_t *bd )
-  {
-  int ret;
-  int i;
-  p_mac = AT91C_BASE_EMAC;
-
-  *AT91C_PIOA_PDR = AT91C_PA16_EMDIO |
-    AT91C_PA15_EMDC | AT91C_PA14_ERXER | AT91C_PA13_ERX1 | AT91C_PA12_ERX0 |
-    AT91C_PA11_ECRS_ECRSDV | AT91C_PA10_ETX1 | AT91C_PA9_ETX0 | AT91C_PA8_ETXEN |
-    AT91C_PA7_ETXCK_EREFCK; 	/* PIO Disable Register */
-
-  *AT91C_PIOB_PDR = AT91C_PB25_EF100 |
-    AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 |
-    AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2;
-
-  *AT91C_PIOB_BSR = AT91C_PB25_EF100 |
-    AT91C_PB19_ERXCK | AT91C_PB18_ECOL | AT91C_PB17_ERXDV | AT91C_PB16_ERX3 |
-    AT91C_PB15_ERX2 | AT91C_PB14_ETXER | AT91C_PB13_ETX3 | AT91C_PB12_ETX2;  /* Select B Register */
-  *AT91C_PMC_PCER = 1 << AT91C_ID_EMAC;  /* Peripheral Clock Enable Register */
-  p_mac->EMAC_CFG |= AT91C_EMAC_CSR;  /* Clear statistics */
-
-  rbfdt=(rbf_t *)RBF_FRAMEBTD;
-  for(i = 0; i < RBF_FRAMEMAX; i++)
-    {
-    rbfdt[i].addr=RBF_FRAMEBUF+RBF_FRAMELEN*i;
-    rbfdt[i].size=0;
-    }
-  rbfdt[RBF_FRAMEMAX-1].addr|=RBF_WRAP;
-  rbfp=&rbfdt[0];
-
-  if (!(ret = MDIO_StartupPhy()))
-    {
-    printf("MAC: error during MII initialization\n");
-    return 0;
-    }
-
-  p_mac->EMAC_SA2L = (bd->bi_enetaddr[3] << 24) | (bd->bi_enetaddr[2] << 16)
-    | (bd->bi_enetaddr[1] <<  8) | (bd->bi_enetaddr[0]);
-  p_mac->EMAC_SA2H = (bd->bi_enetaddr[5] <<  8) | (bd->bi_enetaddr[4]);
-
-  p_mac->EMAC_RBQP = (long)(&rbfdt[0]);
-  p_mac->EMAC_RSR &= ~(AT91C_EMAC_RSR_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
-  p_mac->EMAC_CFG = (p_mac->EMAC_CFG | AT91C_EMAC_CAF | AT91C_EMAC_NBC | AT91C_EMAC_RMII) & ~AT91C_EMAC_CLK;
-  p_mac->EMAC_CTL |= AT91C_EMAC_TE | AT91C_EMAC_RE ;
-
-  return 0;
-  }
-
-int eth_send(volatile void *packet, int length)
-  {
-  while(!(p_mac->EMAC_TSR & AT91C_EMAC_BNQ))
-    ;
-  p_mac->EMAC_TAR = (long)packet;
-  p_mac->EMAC_TCR = length;
-  while(p_mac->EMAC_TCR & 0x7ff)
-    ;
-  p_mac->EMAC_TSR |= AT91C_EMAC_COMP;
-  return 0;
-  }
-
-int eth_rx(void)
-  {
-  int size;
-
-  if(!(rbfp->addr & RBF_OWNER))
-    return 0;
-
-  size=rbfp->size & RBF_SIZE;
-  NetReceive((volatile uchar *) (rbfp->addr & RBF_ADDR), size);
-
-  rbfp->addr &= ~RBF_OWNER;
-  if(rbfp->addr & RBF_WRAP)
-    rbfp = &rbfdt[0];
-  else
-    rbfp++;
-
-  p_mac->EMAC_RSR |= AT91C_EMAC_REC;
-
-  return size;
-  }
-
-void eth_halt( void )
- {};
-#endif
-#endif
diff --git a/drivers/dataflash.c b/drivers/dataflash.c
new file mode 100644
index 0000000..a0a4b62
--- /dev/null
+++ b/drivers/dataflash.c
@@ -0,0 +1,245 @@
+/* LowLevel function for ATMEL DataFlash support
+ * Author : Hamid Ikdoumi (Atmel)
+ *
+ * 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 <config.h>
+#ifdef CONFIG_HAS_DATAFLASH
+#include <asm/hardware.h>
+#include <dataflash.h>
+
+AT91S_DATAFLASH_INFO dataflash_info[CFG_MAX_DATAFLASH_BANKS];
+static AT91S_DataFlash DataFlashInst;
+
+int cs[][CFG_MAX_DATAFLASH_BANKS] = {
+	{CFG_DATAFLASH_LOGIC_ADDR_CS0, 0},	/* Logical adress, CS */
+	{CFG_DATAFLASH_LOGIC_ADDR_CS3, 3}
+};
+
+extern void AT91F_SpiInit (void);
+extern int AT91F_DataflashProbe (int i, AT91PS_DataflashDesc pDesc);
+extern int AT91F_DataFlashRead (AT91PS_DataFlash pDataFlash,
+				unsigned long addr,
+				unsigned long size, char *buffer);
+
+
+int AT91F_DataflashInit (void)
+{
+	int i, j;
+	int dfcode;
+
+	AT91F_SpiInit ();
+
+	for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
+
+		dataflash_info[i].id = 0;
+		dataflash_info[i].Device.pages_number = 0;
+		dfcode = AT91F_DataflashProbe (cs[i][1], &dataflash_info[i].Desc);
+
+		switch (dfcode) {
+		case AT45DB161:
+			dataflash_info[i].Device.pages_number = 4096;
+			dataflash_info[i].Device.pages_size = 528;
+			dataflash_info[i].Device.page_offset = 10;
+			dataflash_info[i].Device.byte_mask = 0x300;
+			dataflash_info[i].Device.cs = cs[i][1];
+			dataflash_info[i].Desc.DataFlash_state = IDLE;
+			dataflash_info[i].logical_address = cs[i][0];
+			dataflash_info[i].id = dfcode;
+			break;
+
+		case AT45DB321:
+			dataflash_info[i].Device.pages_number = 8192;
+			dataflash_info[i].Device.pages_size = 528;
+			dataflash_info[i].Device.page_offset = 10;
+			dataflash_info[i].Device.byte_mask = 0x300;
+			dataflash_info[i].Device.cs = cs[i][1];
+			dataflash_info[i].Desc.DataFlash_state = IDLE;
+			dataflash_info[i].logical_address = cs[i][0];
+			dataflash_info[i].id = dfcode;
+			break;
+
+		case AT45DB642:
+			dataflash_info[i].Device.pages_number = 8192;
+			dataflash_info[i].Device.pages_size = 1056;
+			dataflash_info[i].Device.page_offset = 11;
+			dataflash_info[i].Device.byte_mask = 0x700;
+			dataflash_info[i].Device.cs = cs[i][1];
+			dataflash_info[i].Desc.DataFlash_state = IDLE;
+			dataflash_info[i].logical_address = cs[i][0];
+			dataflash_info[i].id = dfcode;
+			break;
+
+		default:
+			break;
+		}
+
+		for (j = 0; j < dataflash_info[i].Device.pages_number; j++)
+			dataflash_info[i].protect[j] = FLAG_PROTECT_SET;
+
+	}
+	return (1);
+}
+
+
+
+void dataflash_print_info (void)
+{
+	int i;
+
+	for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
+		if (dataflash_info[i].id != 0) {
+			printf ("DataFlash:");
+			switch (dataflash_info[i].id) {
+			case AT45DB161:
+				printf ("AT45DB161\n");
+				break;
+
+			case AT45DB321:
+				printf ("AT45DB321\n");
+				break;
+
+			case AT45DB642:
+				printf ("AT45DB642\n");
+				break;
+			}
+
+			printf ("Nb pages: %6d\n"
+				"Page Size: %6d\n"
+				"Size=%8d bytes\n"
+				"Logical address: 0x%08X\n",
+				(unsigned int) dataflash_info[i].Device.pages_number,
+				(unsigned int) dataflash_info[i].Device.pages_size,
+				(unsigned int) dataflash_info[i].Device.pages_number *
+				dataflash_info[i].Device.pages_size,
+				(unsigned int) dataflash_info[i].logical_address);
+		}
+	}
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataflashSelect 					*/
+/* Object              : Select the correct device				*/
+/*------------------------------------------------------------------------------*/
+AT91PS_DataFlash AT91F_DataflashSelect (AT91PS_DataFlash pFlash,
+										unsigned int *addr)
+{
+	char addr_valid = 0;
+	int i;
+
+	for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++)
+		if ((*addr & 0xFF000000) == dataflash_info[i].logical_address) {
+			addr_valid = 1;
+			break;
+		}
+	if (!addr_valid) {
+		pFlash = (AT91PS_DataFlash) 0;
+		return pFlash;
+	}
+	pFlash->pDataFlashDesc = &(dataflash_info[i].Desc);
+	pFlash->pDevice = &(dataflash_info[i].Device);
+	*addr -= dataflash_info[i].logical_address;
+	return (pFlash);
+}
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : addr_dataflash 					*/
+/* Object              : Test if address is valid				*/
+/*------------------------------------------------------------------------------*/
+int addr_dataflash (unsigned long addr)
+{
+	int addr_valid = 0;
+	int i;
+
+	for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
+		if ((((int) addr) & 0xFF000000) ==
+			dataflash_info[i].logical_address) {
+			addr_valid = 1;
+			break;
+		}
+	}
+
+	return addr_valid;
+}
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : read_dataflash 					*/
+/* Object              : dataflash memory read					*/
+/*------------------------------------------------------------------------------*/
+int read_dataflash (unsigned long addr, unsigned long size, char *result)
+{
+	int AddrToRead = addr;
+	AT91PS_DataFlash pFlash = &DataFlashInst;
+
+	pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead);
+	if (pFlash == 0)
+		return -1;
+
+	return (AT91F_DataFlashRead (pFlash, AddrToRead, size, result));
+}
+
+
+/*-----------------------------------------------------------------------------*/
+/* Function Name       : write_dataflash 				       */
+/* Object              : write a block in dataflash			       */
+/*-----------------------------------------------------------------------------*/
+int write_dataflash (unsigned long addr_dest, unsigned long addr_src,
+		     unsigned long size)
+{
+	extern AT91S_DataFlashStatus AT91F_DataFlashWrite(
+			AT91PS_DataFlash, uchar *, int, int);
+	int AddrToWrite = addr_dest;
+	AT91PS_DataFlash pFlash = &DataFlashInst;
+
+	pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite);
+	if (AddrToWrite == -1)
+		return -1;
+
+	return AT91F_DataFlashWrite (pFlash, (char *) addr_src, AddrToWrite,
+								 size);
+}
+
+
+void dataflash_perror (int err)
+{
+	switch (err) {
+	case ERR_OK:
+		break;
+	case ERR_TIMOUT:
+		printf ("Timeout writing to DataFlash\n");
+		break;
+	case ERR_PROTECTED:
+		printf ("Can't write to protected DataFlash sectors\n");
+		break;
+	case ERR_INVAL:
+		printf ("Outside available DataFlash\n");
+		break;
+	case ERR_UNKNOWN_FLASH_TYPE:
+		printf ("Unknown Type of DataFlash\n");
+		break;
+	case ERR_PROG_ERROR:
+		printf ("General DataFlash Programming Error\n");
+		break;
+	default:
+		printf ("%s[%d] FIXME: rc=%d\n", __FILE__, __LINE__, err);
+		break;
+	}
+}
+
+#endif
diff --git a/include/asm-arm/arch-at91rm9200/AT91RM9200.h b/include/asm-arm/arch-at91rm9200/AT91RM9200.h
index 8f93c12..c0e5211 100644
--- a/include/asm-arm/arch-at91rm9200/AT91RM9200.h
+++ b/include/asm-arm/arch-at91rm9200/AT91RM9200.h
@@ -1,15 +1,27 @@
-/* ---------------------------------------------------------------------------- */
-/*          ATMEL Microcontroller Software Support  -  ROUSSET  - */
-/* ---------------------------------------------------------------------------- */
-/*  The software is delivered "AS IS" without warranty or condition of any */
-/*  kind, either express, implied or statutory. This includes without */
-/*  limitation any warranty or condition with respect to merchantability or */
-/*  fitness for any particular purpose, or against the infringements of */
-/*  intellectual property rights of others. */
-/* ---------------------------------------------------------------------------- */
-/* File Name           : AT91RM9200.h */
-/* Object              : AT91RM9200 definitions */
-/* Generated           : AT91 SW Application Group  10/29/2002 (16:10:51) */
+/*
+ * (C) Copyright 2003
+ * AT91RM9200 definitions
+ * Author : ATMEL AT91 application group
+ *
+ * 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 AT91RM9200_H
 #define AT91RM9200_H
 
@@ -32,6 +44,21 @@
 	AT91_REG	 TC_IMR; 	/* Interrupt Mask Register */
 } AT91S_TC, *AT91PS_TC;
 
+#define AT91C_TC_TIMER_DIV1_CLOCK      ((unsigned int) 0x0 <<  0) /* (TC) MCK/2 */
+#define AT91C_TC_TIMER_DIV2_CLOCK      ((unsigned int) 0x1 <<  0) /* (TC) MCK/8 */
+#define AT91C_TC_TIMER_DIV3_CLOCK      ((unsigned int) 0x2 <<  0) /* (TC) MCK/32 */
+#define AT91C_TC_TIMER_DIV4_CLOCK      ((unsigned int) 0x3 <<  0) /* (TC) MCK/128 */
+#define AT91C_TC_SLOW_CLOCK            ((unsigned int) 0x4 <<  0) /* (TC) SLOW CLK */
+#define AT91C_TC_XC0_CLOCK             ((unsigned int) 0x5 <<  0) /* (TC) XC0 */
+#define AT91C_TC_XC1_CLOCK             ((unsigned int) 0x6 <<  0) /* (TC) XC1 */
+#define AT91C_TC_XC2_CLOCK             ((unsigned int) 0x7 <<  0) /* (TC) XC2 */
+#define 	AT91C_TCB_TC0XC0S_NONE                 ((unsigned int) 0x1) /* (TCB) None signal connected to XC0 */
+#define 	AT91C_TCB_TC1XC1S_NONE                 ((unsigned int) 0x1 <<  2) /* (TCB) None signal connected to XC1 */
+#define 	AT91C_TCB_TC2XC2S_NONE                 ((unsigned int) 0x1 <<  4) /* (TCB) None signal connected to XC2 */
+#define AT91C_TC_CLKDIS       ((unsigned int) 0x1 <<  1) /* (TC) Counter Clock Disable Command */
+#define AT91C_TC_SWTRG        ((unsigned int) 0x1 <<  2) /* (TC) Software Trigger Command */
+#define AT91C_TC_CLKEN        ((unsigned int) 0x1 <<  0) /* (TC) Counter Clock Enable Command */
+
 /* ***************************************************************************** */
 /*              SOFTWARE API DEFINITION  FOR Usart */
 /* ***************************************************************************** */
@@ -137,6 +164,32 @@
 	AT91_REG	 DBGU_PTSR; 	/* PDC Transfer Status Register */
 } AT91S_DBGU, *AT91PS_DBGU;
 
+/* -------- DBGU_IER : (DBGU Offset: 0x8) Debug Unit Interrupt Enable Register --------  */
+#define AT91C_US_RXRDY        ((unsigned int) 0x1 <<  0) /* (DBGU) RXRDY Interrupt */
+#define AT91C_US_TXRDY        ((unsigned int) 0x1 <<  1) /* (DBGU) TXRDY Interrupt */
+#define AT91C_US_ENDRX        ((unsigned int) 0x1 <<  3) /* (DBGU) End of Receive Transfer Interrupt */
+#define AT91C_US_ENDTX        ((unsigned int) 0x1 <<  4) /* (DBGU) End of Transmit Interrupt */
+#define AT91C_US_OVRE         ((unsigned int) 0x1 <<  5) /* (DBGU) Overrun Interrupt */
+#define AT91C_US_FRAME        ((unsigned int) 0x1 <<  6) /* (DBGU) Framing Error Interrupt */
+#define AT91C_US_PARE         ((unsigned int) 0x1 <<  7) /* (DBGU) Parity Error Interrupt */
+#define AT91C_US_TXEMPTY      ((unsigned int) 0x1 <<  9) /* (DBGU) TXEMPTY Interrupt */
+#define AT91C_US_TXBUFE       ((unsigned int) 0x1 << 11) /* (DBGU) TXBUFE Interrupt */
+#define AT91C_US_RXBUFF       ((unsigned int) 0x1 << 12) /* (DBGU) RXBUFF Interrupt */
+#define AT91C_US_COMM_TX      ((unsigned int) 0x1 << 30) /* (DBGU) COMM_TX Interrupt */
+#define AT91C_US_COMM_RX      ((unsigned int) 0x1 << 31) /* (DBGU) COMM_RX Interrupt */
+
+/* -------- DBGU_CR : (DBGU Offset: 0x0) Debug Unit Control Register --------  */
+#define AT91C_US_RSTRX        ((unsigned int) 0x1 <<  2) /* (DBGU) Reset Receiver */
+#define AT91C_US_RSTTX        ((unsigned int) 0x1 <<  3) /* (DBGU) Reset Transmitter */
+#define AT91C_US_RXEN         ((unsigned int) 0x1 <<  4) /* (DBGU) Receiver Enable */
+#define AT91C_US_RXDIS        ((unsigned int) 0x1 <<  5) /* (DBGU) Receiver Disable */
+#define AT91C_US_TXEN         ((unsigned int) 0x1 <<  6) /* (DBGU) Transmitter Enable */
+#define AT91C_US_TXDIS        ((unsigned int) 0x1 <<  7) /* (DBGU) Transmitter Disable */
+
+#define AT91C_US_CLKS_CLOCK             ((unsigned int) 0x0 <<  4) /* (USART) Clock */
+#define AT91C_US_CHRL_8_BITS            ((unsigned int) 0x3 <<  6) /* (USART) Character Length: 8 bits */
+#define AT91C_US_PAR_NONE               ((unsigned int) 0x4 <<  9) /* (DBGU) No Parity */
+#define AT91C_US_NBSTOP_1_BIT           ((unsigned int) 0x0 << 12) /* (USART) 1 stop bit */
 
 /* ***************************************************************************** */
 /*              SOFTWARE API DEFINITION  FOR Static Memory Controller 2 Interface */
@@ -146,6 +199,28 @@
 } AT91S_SMC2, *AT91PS_SMC2;
 
 /* ***************************************************************************** */
+/*              SOFTWARE API DEFINITION  FOR Power Management Controler		*/
+/* ******************************************************************************/
+typedef struct _AT91S_PMC {
+	AT91_REG	 PMC_SCER; 	/* System Clock Enable Register */
+	AT91_REG	 PMC_SCDR; 	/* System Clock Disable Register */
+	AT91_REG	 PMC_SCSR; 	/* System Clock Status Register */
+	AT91_REG	 Reserved0[1]; 	/* */ 
+	AT91_REG	 PMC_PCER; 	/* Peripheral Clock Enable Register */
+	AT91_REG	 PMC_PCDR; 	/* Peripheral Clock Disable Register */
+	AT91_REG	 PMC_PCSR; 	/* Peripheral Clock Status Register */
+	AT91_REG	 Reserved1[5]; 	/* */ 
+	AT91_REG	 PMC_MCKR; 	/* Master Clock Register */
+	AT91_REG	 Reserved2[3]; 	/* */ 
+	AT91_REG	 PMC_PCKR[8]; 	/* Programmable Clock Register */
+	AT91_REG	 PMC_IER; 	/* Interrupt Enable Register */
+	AT91_REG	 PMC_IDR; 	/* Interrupt Disable Register */
+	AT91_REG	 PMC_SR; 	/* Status Register */
+	AT91_REG	 PMC_IMR; 	/* Interrupt Mask Register */
+} AT91S_PMC, *AT91PS_PMC;
+
+
+/* ***************************************************************************** */
 /*              SOFTWARE API DEFINITION  FOR Ethernet MAC */
 /* ***************************************************************************** */
 typedef struct _AT91S_EMAC {
@@ -194,35 +269,185 @@
 	AT91_REG	 EMAC_SA4H; 	/* Specific Address 4 High, Last 2 bytesr */
 } AT91S_EMAC, *AT91PS_EMAC;
 
-/* -------- DBGU_IER : (DBGU Offset: 0x8) Debug Unit Interrupt Enable Register --------  */
-#define AT91C_US_RXRDY        ((unsigned int) 0x1 <<  0) /* (DBGU) RXRDY Interrupt */
-#define AT91C_US_TXRDY        ((unsigned int) 0x1 <<  1) /* (DBGU) TXRDY Interrupt */
-#define AT91C_US_ENDRX        ((unsigned int) 0x1 <<  3) /* (DBGU) End of Receive Transfer Interrupt */
-#define AT91C_US_ENDTX        ((unsigned int) 0x1 <<  4) /* (DBGU) End of Transmit Interrupt */
-#define AT91C_US_OVRE         ((unsigned int) 0x1 <<  5) /* (DBGU) Overrun Interrupt */
-#define AT91C_US_FRAME        ((unsigned int) 0x1 <<  6) /* (DBGU) Framing Error Interrupt */
-#define AT91C_US_PARE         ((unsigned int) 0x1 <<  7) /* (DBGU) Parity Error Interrupt */
-#define AT91C_US_TXEMPTY      ((unsigned int) 0x1 <<  9) /* (DBGU) TXEMPTY Interrupt */
-#define AT91C_US_TXBUFE       ((unsigned int) 0x1 << 11) /* (DBGU) TXBUFE Interrupt */
-#define AT91C_US_RXBUFF       ((unsigned int) 0x1 << 12) /* (DBGU) RXBUFF Interrupt */
-#define AT91C_US_COMM_TX      ((unsigned int) 0x1 << 30) /* (DBGU) COMM_TX Interrupt */
-#define AT91C_US_COMM_RX      ((unsigned int) 0x1 << 31) /* (DBGU) COMM_RX Interrupt */
+/* -------- EMAC_CTL : (EMAC Offset: 0x0)  --------  */
+#define AT91C_EMAC_LB         ((unsigned int) 0x1 <<  0) /* (EMAC) Loopback. Optional. When set, loopback signal is at high level. */
+#define AT91C_EMAC_LBL        ((unsigned int) 0x1 <<  1) /* (EMAC) Loopback local. */
+#define AT91C_EMAC_RE         ((unsigned int) 0x1 <<  2) /* (EMAC) Receive enable. */
+#define AT91C_EMAC_TE         ((unsigned int) 0x1 <<  3) /* (EMAC) Transmit enable. */
+#define AT91C_EMAC_MPE        ((unsigned int) 0x1 <<  4) /* (EMAC) Management port enable. */
+#define AT91C_EMAC_CSR        ((unsigned int) 0x1 <<  5) /* (EMAC) Clear statistics registers. */
+#define AT91C_EMAC_ISR        ((unsigned int) 0x1 <<  6) /* (EMAC) Increment statistics registers. */
+#define AT91C_EMAC_WES        ((unsigned int) 0x1 <<  7) /* (EMAC) Write enable for statistics registers. */
+#define AT91C_EMAC_BP         ((unsigned int) 0x1 <<  8) /* (EMAC) Back pressure. */
+/* -------- EMAC_CFG : (EMAC Offset: 0x4) Network Configuration Register --------  */
+#define AT91C_EMAC_SPD        ((unsigned int) 0x1 <<  0) /* (EMAC) Speed. */
+#define AT91C_EMAC_FD         ((unsigned int) 0x1 <<  1) /* (EMAC) Full duplex. */ 
+#define AT91C_EMAC_BR         ((unsigned int) 0x1 <<  2) /* (EMAC) Bit rate. */
+#define AT91C_EMAC_CAF        ((unsigned int) 0x1 <<  4) /* (EMAC) Copy all frames. */ 
+#define AT91C_EMAC_NBC        ((unsigned int) 0x1 <<  5) /* (EMAC) No broadcast. */
+#define AT91C_EMAC_MTI        ((unsigned int) 0x1 <<  6) /* (EMAC) Multicast hash enable */
+#define AT91C_EMAC_UNI        ((unsigned int) 0x1 <<  7) /* (EMAC) Unicast hash enable. */
+#define AT91C_EMAC_BIG        ((unsigned int) 0x1 <<  8) /* (EMAC) Receive 1522 bytes. */
+#define AT91C_EMAC_EAE        ((unsigned int) 0x1 <<  9) /* (EMAC) External address match enable. */
+#define AT91C_EMAC_CLK        ((unsigned int) 0x3 << 10) /* (EMAC) */
+#define 	AT91C_EMAC_CLK_HCLK_8               ((unsigned int) 0x0 << 10) /* (EMAC) HCLK divided by 8 */
+#define 	AT91C_EMAC_CLK_HCLK_16              ((unsigned int) 0x1 << 10) /* (EMAC) HCLK divided by 16 */
+#define 	AT91C_EMAC_CLK_HCLK_32              ((unsigned int) 0x2 << 10) /* (EMAC) HCLK divided by 32 */
+#define 	AT91C_EMAC_CLK_HCLK_64              ((unsigned int) 0x3 << 10) /* (EMAC) HCLK divided by 64 */
+#define AT91C_EMAC_RTY        ((unsigned int) 0x1 << 12) /* (EMAC) */
+#define AT91C_EMAC_RMII       ((unsigned int) 0x1 << 13) /* (EMAC) */
+/* -------- EMAC_SR : (EMAC Offset: 0x8) Network Status Register --------  */
+#define AT91C_EMAC_MDIO       ((unsigned int) 0x1 <<  1) /* (EMAC) */
+#define AT91C_EMAC_IDLE       ((unsigned int) 0x1 <<  2) /* (EMAC) */
+/* -------- EMAC_TCR : (EMAC Offset: 0x10) Transmit Control Register -------- */
+#define AT91C_EMAC_LEN        ((unsigned int) 0x7FF <<  0) /* (EMAC) */
+#define AT91C_EMAC_NCRC       ((unsigned int) 0x1 << 15) /* (EMAC) */
+/* -------- EMAC_TSR : (EMAC Offset: 0x14) Transmit Control Register -------- */
+#define AT91C_EMAC_OVR        ((unsigned int) 0x1 <<  0) /* (EMAC) */
+#define AT91C_EMAC_COL        ((unsigned int) 0x1 <<  1) /* (EMAC) */
+#define AT91C_EMAC_RLE        ((unsigned int) 0x1 <<  2) /* (EMAC) */
+#define AT91C_EMAC_TXIDLE     ((unsigned int) 0x1 <<  3) /* (EMAC) */
+#define AT91C_EMAC_BNQ        ((unsigned int) 0x1 <<  4) /* (EMAC) */
+#define AT91C_EMAC_COMP       ((unsigned int) 0x1 <<  5) /* (EMAC) */
+#define AT91C_EMAC_UND        ((unsigned int) 0x1 <<  6) /* (EMAC) */
+/* -------- EMAC_RSR : (EMAC Offset: 0x20) Receive Status Register -------- */
+#define AT91C_EMAC_BNA        ((unsigned int) 0x1 <<  0) /* (EMAC) */
+#define AT91C_EMAC_REC        ((unsigned int) 0x1 <<  1) /* (EMAC) */
+#define AT91C_EMAC_RSR_OVR    ((unsigned int) 0x1 <<  2) /* (EMAC) */
+/* -------- EMAC_ISR : (EMAC Offset: 0x24) Interrupt Status Register -------- */
+#define AT91C_EMAC_DONE       ((unsigned int) 0x1 <<  0) /* (EMAC) */
+#define AT91C_EMAC_RCOM       ((unsigned int) 0x1 <<  1) /* (EMAC) */
+#define AT91C_EMAC_RBNA       ((unsigned int) 0x1 <<  2) /* (EMAC) */
+#define AT91C_EMAC_TOVR       ((unsigned int) 0x1 <<  3) /* (EMAC) */
+#define AT91C_EMAC_TUND       ((unsigned int) 0x1 <<  4) /* (EMAC) */
+#define AT91C_EMAC_RTRY       ((unsigned int) 0x1 <<  5) /* (EMAC) */
+#define AT91C_EMAC_TBRE       ((unsigned int) 0x1 <<  6) /* (EMAC) */
+#define AT91C_EMAC_TCOM       ((unsigned int) 0x1 <<  7) /* (EMAC) */
+#define AT91C_EMAC_TIDLE      ((unsigned int) 0x1 <<  8) /* (EMAC) */
+#define AT91C_EMAC_LINK       ((unsigned int) 0x1 <<  9) /* (EMAC) */
+#define AT91C_EMAC_ROVR       ((unsigned int) 0x1 << 10) /* (EMAC) */
+#define AT91C_EMAC_HRESP      ((unsigned int) 0x1 << 11) /* (EMAC) */
+/* -------- EMAC_IER : (EMAC Offset: 0x28) Interrupt Enable Register -------- */
+/* -------- EMAC_IDR : (EMAC Offset: 0x2c) Interrupt Disable Register -------- */ 
+/* -------- EMAC_IMR : (EMAC Offset: 0x30) Interrupt Mask Register -------- */
+/* -------- EMAC_MAN : (EMAC Offset: 0x34) PHY Maintenance Register -------- */
+#define AT91C_EMAC_DATA       ((unsigned int) 0xFFFF <<  0) /* (EMAC) */ 
+#define AT91C_EMAC_CODE       ((unsigned int) 0x3 << 16) /* (EMAC) */
+#define         AT91C_EMAC_CODE_802_3 ((unsigned int) 0x2 << 16) /* (EMAC) Write Operation */
+#define AT91C_EMAC_REGA       ((unsigned int) 0x1F << 18) /* (EMAC) */
+#define AT91C_EMAC_PHYA       ((unsigned int) 0x1F << 23) /* (EMAC) */
+#define AT91C_EMAC_RW         ((unsigned int) 0x3 << 28) /* (EMAC) */
+#define         AT91C_EMAC_RW_R       ((unsigned int) 0x2 << 28) /* (EMAC) Read Operation */
+#define         AT91C_EMAC_RW_W       ((unsigned int) 0x1 << 28) /* (EMAC) Write Operation */
+#define AT91C_EMAC_HIGH       ((unsigned int) 0x1 << 30) /* (EMAC) */
+#define AT91C_EMAC_LOW        ((unsigned int) 0x1 << 31) /* (EMAC) */
 
-/* -------- DBGU_CR : (DBGU Offset: 0x0) Debug Unit Control Register --------  */
-#define AT91C_US_RSTRX        ((unsigned int) 0x1 <<  2) /* (DBGU) Reset Receiver */
-#define AT91C_US_RSTTX        ((unsigned int) 0x1 <<  3) /* (DBGU) Reset Transmitter */
-#define AT91C_US_RXEN         ((unsigned int) 0x1 <<  4) /* (DBGU) Receiver Enable */
-#define AT91C_US_RXDIS        ((unsigned int) 0x1 <<  5) /* (DBGU) Receiver Disable */
-#define AT91C_US_TXEN         ((unsigned int) 0x1 <<  6) /* (DBGU) Transmitter Enable */
-#define AT91C_US_TXDIS        ((unsigned int) 0x1 <<  7) /* (DBGU) Transmitter Disable */
+/* ***************************************************************************** */
+/*              SOFTWARE API DEFINITION  FOR Serial Parallel Interface		*/
+/* ***************************************************************************** */
+typedef struct _AT91S_SPI {
+	AT91_REG	 SPI_CR; 	/* Control Register */
+	AT91_REG	 SPI_MR; 	/* Mode Register */
+	AT91_REG	 SPI_RDR; 	/* Receive Data Register */
+	AT91_REG	 SPI_TDR; 	/* Transmit Data Register */
+	AT91_REG	 SPI_SR; 	/* Status Register */
+	AT91_REG	 SPI_IER; 	/* Interrupt Enable Register */
+	AT91_REG	 SPI_IDR; 	/* Interrupt Disable Register */
+	AT91_REG	 SPI_IMR; 	/* Interrupt Mask Register */
+	AT91_REG	 Reserved0[4]; 	/* */
+	AT91_REG	 SPI_CSR[4]; 	/* Chip Select Register */
+	AT91_REG	 Reserved1[48]; /* */ 
+	AT91_REG	 SPI_RPR; 	/* Receive Pointer Register */
+	AT91_REG	 SPI_RCR; 	/* Receive Counter Register */
+	AT91_REG	 SPI_TPR; 	/* Transmit Pointer Register */
+	AT91_REG	 SPI_TCR; 	/* Transmit Counter Register */
+	AT91_REG	 SPI_RNPR; 	/* Receive Next Pointer Register */
+	AT91_REG	 SPI_RNCR; 	/* Receive Next Counter Register */
+	AT91_REG	 SPI_TNPR; 	/* Transmit Next Pointer Register */
+	AT91_REG	 SPI_TNCR; 	/* Transmit Next Counter Register */
+	AT91_REG	 SPI_PTCR; 	/* PDC Transfer Control Register */
+	AT91_REG	 SPI_PTSR; 	/* PDC Transfer Status Register */
+} AT91S_SPI, *AT91PS_SPI;
 
-#define 	AT91C_US_CLKS_CLOCK                ((unsigned int) 0x0 <<  4) /* (USART) Clock */
-#define 	AT91C_US_CHRL_8_BITS               ((unsigned int) 0x3 <<  6) /* (USART) Character Length: 8 bits */
-#define 	AT91C_US_PAR_NONE                 ((unsigned int) 0x4 <<  9) /* (DBGU) No Parity */
-#define 	AT91C_US_NBSTOP_1_BIT                ((unsigned int) 0x0 << 12) /* (USART) 1 stop bit */
+/* -------- SPI_CR : (SPI Offset: 0x0) SPI Control Register -------- */
+#define AT91C_SPI_SPIEN       ((unsigned int) 0x1 <<  0) /* (SPI) SPI Enable */
+#define AT91C_SPI_SPIDIS      ((unsigned int) 0x1 <<  1) /* (SPI) SPI Disable */
+#define AT91C_SPI_SWRST       ((unsigned int) 0x1 <<  7) /* (SPI) SPI Software reset */
+/* -------- SPI_MR : (SPI Offset: 0x4) SPI Mode Register -------- */
+#define AT91C_SPI_MSTR        ((unsigned int) 0x1 <<  0) /* (SPI) Master/Slave Mode */
+#define AT91C_SPI_PS          ((unsigned int) 0x1 <<  1) /* (SPI) Peripheral Select */
+#define 	AT91C_SPI_PS_FIXED                ((unsigned int) 0x0 <<  1) /* (SPI) Fixed Peripheral Select */
+#define 	AT91C_SPI_PS_VARIABLE             ((unsigned int) 0x1 <<  1) /* (SPI) Variable Peripheral Select */
+#define AT91C_SPI_PCSDEC      ((unsigned int) 0x1 <<  2) /* (SPI) Chip Select Decode */
+#define AT91C_SPI_DIV32       ((unsigned int) 0x1 <<  3) /* (SPI) Clock Selection */
+#define AT91C_SPI_MODFDIS     ((unsigned int) 0x1 <<  4) /* (SPI) Mode Fault Detection */
+#define AT91C_SPI_LLB         ((unsigned int) 0x1 <<  7) /* (SPI) Clock Selection */
+#define AT91C_SPI_PCS         ((unsigned int) 0xF << 16) /* (SPI) Peripheral Chip Select */
+#define AT91C_SPI_DLYBCS      ((unsigned int) 0xFF << 24) /* (SPI) Delay Between Chip Selects */
+/* -------- SPI_RDR : (SPI Offset: 0x8) Receive Data Register -------- */
+#define AT91C_SPI_RD          ((unsigned int) 0xFFFF <<  0) /* (SPI) Receive Data */
+#define AT91C_SPI_RPCS        ((unsigned int) 0xF << 16) /* (SPI) Peripheral Chip Select Status */
+/* -------- SPI_TDR : (SPI Offset: 0xc) Transmit Data Register -------- */
+#define AT91C_SPI_TD          ((unsigned int) 0xFFFF <<  0) /* (SPI) Transmit Data */
+#define AT91C_SPI_TPCS        ((unsigned int) 0xF << 16) /* (SPI) Peripheral Chip Select Status */
+/* -------- SPI_SR : (SPI Offset: 0x10) Status Register -------- */
+#define AT91C_SPI_RDRF        ((unsigned int) 0x1 <<  0) /* (SPI) Receive Data Register Full */
+#define AT91C_SPI_TDRE        ((unsigned int) 0x1 <<  1) /* (SPI) Transmit Data Register Empty */
+#define AT91C_SPI_MODF        ((unsigned int) 0x1 <<  2) /* (SPI) Mode Fault Error */
+#define AT91C_SPI_OVRES       ((unsigned int) 0x1 <<  3) /* (SPI) Overrun Error Status */
+#define AT91C_SPI_SPENDRX     ((unsigned int) 0x1 <<  4) /* (SPI) End of Receiver Transfer */
+#define AT91C_SPI_SPENDTX     ((unsigned int) 0x1 <<  5) /* (SPI) End of Receiver Transfer */
+#define AT91C_SPI_RXBUFF      ((unsigned int) 0x1 <<  6) /* (SPI) RXBUFF Interrupt */
+#define AT91C_SPI_TXBUFE      ((unsigned int) 0x1 <<  7) /* (SPI) TXBUFE Interrupt */
+#define AT91C_SPI_SPIENS      ((unsigned int) 0x1 << 16) /* (SPI) Enable Status */
+/* -------- SPI_IER : (SPI Offset: 0x14) Interrupt Enable Register -------- */
+/* -------- SPI_IDR : (SPI Offset: 0x18) Interrupt Disable Register -------- */
+/* -------- SPI_IMR : (SPI Offset: 0x1c) Interrupt Mask Register -------- */
+/* -------- SPI_CSR : (SPI Offset: 0x30) Chip Select Register -------- */
+#define AT91C_SPI_CPOL        ((unsigned int) 0x1 <<  0) /* (SPI) Clock Polarity */
+#define AT91C_SPI_NCPHA       ((unsigned int) 0x1 <<  1) /* (SPI) Clock Phase */
+#define AT91C_SPI_BITS        ((unsigned int) 0xF <<  4) /* (SPI) Bits Per Transfer */
+#define 	AT91C_SPI_BITS_8                    ((unsigned int) 0x0 <<  4) /* (SPI) 8 Bits Per transfer */
+#define 	AT91C_SPI_BITS_9                    ((unsigned int) 0x1 <<  4) /* (SPI) 9 Bits Per transfer */
+#define 	AT91C_SPI_BITS_10                   ((unsigned int) 0x2 <<  4) /* (SPI) 10 Bits Per transfer */
+#define 	AT91C_SPI_BITS_11                   ((unsigned int) 0x3 <<  4) /* (SPI) 11 Bits Per transfer */
+#define 	AT91C_SPI_BITS_12                   ((unsigned int) 0x4 <<  4) /* (SPI) 12 Bits Per transfer */
+#define 	AT91C_SPI_BITS_13                   ((unsigned int) 0x5 <<  4) /* (SPI) 13 Bits Per transfer */
+#define 	AT91C_SPI_BITS_14                   ((unsigned int) 0x6 <<  4) /* (SPI) 14 Bits Per transfer */
+#define 	AT91C_SPI_BITS_15                   ((unsigned int) 0x7 <<  4) /* (SPI) 15 Bits Per transfer */
+#define 	AT91C_SPI_BITS_16                   ((unsigned int) 0x8 <<  4) /* (SPI) 16 Bits Per transfer */
+#define AT91C_SPI_SCBR        ((unsigned int) 0xFF <<  8) /* (SPI) Serial Clock Baud Rate */
+#define AT91C_SPI_DLYBS       ((unsigned int) 0xFF << 16) /* (SPI) Serial Clock Baud Rate */
+#define AT91C_SPI_DLYBCT      ((unsigned int) 0xFF << 24) /* (SPI) Delay Between Consecutive Transfers */
 
+/* ***************************************************************************** */
+/*              SOFTWARE API DEFINITION  FOR Peripheral Data Controller		*/
+/* ***************************************************************************** */
+typedef struct _AT91S_PDC {
+	AT91_REG	 PDC_RPR; 	/* Receive Pointer Register */
+	AT91_REG	 PDC_RCR; 	/* Receive Counter Register */
+	AT91_REG	 PDC_TPR; 	/* Transmit Pointer Register */
+	AT91_REG	 PDC_TCR; 	/* Transmit Counter Register */
+	AT91_REG	 PDC_RNPR; 	/* Receive Next Pointer Register */
+	AT91_REG	 PDC_RNCR; 	/* Receive Next Counter Register */
+	AT91_REG	 PDC_TNPR; 	/* Transmit Next Pointer Register */
+	AT91_REG	 PDC_TNCR; 	/* Transmit Next Counter Register */
+	AT91_REG	 PDC_PTCR; 	/* PDC Transfer Control Register */
+	AT91_REG	 PDC_PTSR; 	/* PDC Transfer Status Register */
+} AT91S_PDC, *AT91PS_PDC;
+
+/* -------- PDC_PTCR : (PDC Offset: 0x20) PDC Transfer Control Register -------- */
+#define AT91C_PDC_RXTEN       ((unsigned int) 0x1 <<  0) /* (PDC) Receiver Transfer Enable */
+#define AT91C_PDC_RXTDIS      ((unsigned int) 0x1 <<  1) /* (PDC) Receiver Transfer Disable */
+#define AT91C_PDC_TXTEN       ((unsigned int) 0x1 <<  8) /* (PDC) Transmitter Transfer Enable */
+#define AT91C_PDC_TXTDIS      ((unsigned int) 0x1 <<  9) /* (PDC) Transmitter Transfer Disable */
+/* -------- PDC_PTSR : (PDC Offset: 0x24) PDC Transfer Status Register --------  */
+
+/* ========== Register definition ==================================== */
+#define AT91C_SPI_CSR   ((AT91_REG *) 	0xFFFE0030) /* (SPI) Chip Select Register */
 #define AT91C_PMC_PCER  ((AT91_REG *) 	0xFFFFFC10) /* (PMC) Peripheral Clock Enable Register */
 #define AT91C_PIOA_PDR  ((AT91_REG *) 	0xFFFFF404) /* (PIOA) PIO Disable Register */
+
 #define AT91C_PIO_PA30       ((unsigned int) 1 << 30) /* Pin Controlled by PA30 */
 #define AT91C_PIO_PC0        ((unsigned int) 1 <<  0) /* Pin Controlled by PC0 */
 #define AT91C_PC0_BFCK     ((unsigned int) AT91C_PIO_PC0) /*  Burst Flash Clock */
@@ -233,6 +458,7 @@
 #define AT91C_ID_SYS    ((unsigned int)  1) /* System Peripheral */
 #define AT91C_ID_TC0    ((unsigned int) 17) /* Timer Counter 0 */
 #define AT91C_ID_EMAC   ((unsigned int) 24) /* Ethernet MAC */
+#define AT91C_ID_SPI    ((unsigned int) 13) /* Serial Peripheral Interface */
 
 #define AT91C_PIO_PC1        ((unsigned int) 1 <<  1) /* Pin Controlled by PC1 */
 #define AT91C_PC1_BFRDY_SMOE ((unsigned int) AT91C_PIO_PC1) /*  Burst Flash Ready */
@@ -242,38 +468,25 @@
 #define AT91C_PC2_BFAVD    ((unsigned int) AT91C_PIO_PC2) /*  Burst Flash Address Valid */
 #define AT91C_PIO_PB1        ((unsigned int) 1 <<  1) /* Pin Controlled by PB1 */
 
-#define AT91C_TC_TIMER_DIV1_CLOCK      ((unsigned int) 0x0 <<  0) /* (TC) MCK/2 */
-#define AT91C_TC_TIMER_DIV2_CLOCK      ((unsigned int) 0x1 <<  0) /* (TC) MCK/8 */
-#define AT91C_TC_TIMER_DIV3_CLOCK      ((unsigned int) 0x2 <<  0) /* (TC) MCK/32 */
-#define AT91C_TC_TIMER_DIV4_CLOCK      ((unsigned int) 0x3 <<  0) /* (TC) MCK/128 */
-#define AT91C_TC_SLOW_CLOCK            ((unsigned int) 0x4 <<  0) /* (TC) SLOW CLK */
-#define AT91C_TC_XC0_CLOCK             ((unsigned int) 0x5 <<  0) /* (TC) XC0 */
-#define AT91C_TC_XC1_CLOCK             ((unsigned int) 0x6 <<  0) /* (TC) XC1 */
-#define AT91C_TC_XC2_CLOCK             ((unsigned int) 0x7 <<  0) /* (TC) XC2 */
-#define 	AT91C_TCB_TC0XC0S_NONE                 ((unsigned int) 0x1) /* (TCB) None signal connected to XC0 */
-#define 	AT91C_TCB_TC1XC1S_NONE                 ((unsigned int) 0x1 <<  2) /* (TCB) None signal connected to XC1 */
-#define 	AT91C_TCB_TC2XC2S_NONE                 ((unsigned int) 0x1 <<  4) /* (TCB) None signal connected to XC2 */
-#define AT91C_TC_CLKDIS       ((unsigned int) 0x1 <<  1) /* (TC) Counter Clock Disable Command */
-#define AT91C_TC_SWTRG        ((unsigned int) 0x1 <<  2) /* (TC) Software Trigger Command */
-#define AT91C_TC_CLKEN        ((unsigned int) 0x1 <<  0) /* (TC) Counter Clock Enable Command */
+#define AT91C_PIO_PA23       ((unsigned int) 1 << 23) /* Pin Controlled by PA23 */
+#define AT91C_PA23_TXD2     ((unsigned int) AT91C_PIO_PA23) /* USART 2 Transmit Data */
 
-#define AT91C_EMAC_BNQ        ((unsigned int) 0x1 <<  4) /* (EMAC)  */
-#define AT91C_EMAC_COMP       ((unsigned int) 0x1 <<  5) /* (EMAC)  */
-#define AT91C_EMAC_REC        ((unsigned int) 0x1 <<  1) /* (EMAC)  */
-#define AT91C_EMAC_RE         ((unsigned int) 0x1 <<  2) /* (EMAC) Receive enable.  */
-#define AT91C_EMAC_TE         ((unsigned int) 0x1 <<  3) /* (EMAC) Transmit enable.  */
-#define AT91C_EMAC_CLK        ((unsigned int) 0x3 << 10) /* (EMAC)  */
-#define AT91C_EMAC_RMII       ((unsigned int) 0x1 << 13) /* (EMAC)  */
-#define AT91C_EMAC_NBC        ((unsigned int) 0x1 <<  5) /* (EMAC) No broadcast.  */
-#define AT91C_EMAC_CAF        ((unsigned int) 0x1 <<  4) /* (EMAC) Copy all frames.  */
-#define AT91C_EMAC_BNA        ((unsigned int) 0x1 <<  0) /* (EMAC)  */
-#define AT91C_EMAC_REC        ((unsigned int) 0x1 <<  1) /* (EMAC)  */
-#define AT91C_EMAC_RSR_OVR    ((unsigned int) 0x1 <<  2) /* (EMAC)  */
-#define AT91C_EMAC_CSR        ((unsigned int) 0x1 <<  5) /* (EMAC) Clear statistics registers.  */
-#define AT91C_EMAC_SPD        ((unsigned int) 0x1 <<  0) /* (EMAC) Speed.  */
-#define AT91C_EMAC_FD         ((unsigned int) 0x1 <<  1) /* (EMAC) Full duplex.  */
-#define AT91C_EMAC_LINK       ((unsigned int) 0x1 <<  0) /* (EMAC)  */
-#define AT91C_EMAC_MPE        ((unsigned int) 0x1 <<  4) /* (EMAC) Management port enable.  */
+#define AT91C_PIO_PA0        ((unsigned int) 1 <<  0) /* Pin Controlled by PA0 */
+#define AT91C_PA0_MISO     ((unsigned int) AT91C_PIO_PA0) /* SPI Master In Slave */
+#define AT91C_PIO_PA1        ((unsigned int) 1 <<  1) /* Pin Controlled by PA1 */
+#define AT91C_PA1_MOSI     ((unsigned int) AT91C_PIO_PA1) /* SPI Master Out Slave */
+#define AT91C_PIO_PA2        ((unsigned int) 1 <<  2) /* Pin Controlled by PA2 */
+#define AT91C_PA2_SPCK     ((unsigned int) AT91C_PIO_PA2) /* SPI Serial Clock */
+#define AT91C_PIO_PA3        ((unsigned int) 1 <<  3) /* Pin Controlled by PA3 */
+#define AT91C_PA3_NPCS0    ((unsigned int) AT91C_PIO_PA3) /* SPI Peripheral Chip Select 0 */
+#define AT91C_PIO_PA4        ((unsigned int) 1 <<  4) /* Pin Controlled by PA4 */
+#define AT91C_PA4_NPCS1    ((unsigned int) AT91C_PIO_PA4) /* SPI Peripheral Chip Select 1 */
+#define AT91C_PIO_PA5        ((unsigned int) 1 <<  5) /* Pin Controlled by PA5 */
+#define AT91C_PA5_NPCS2    ((unsigned int) AT91C_PIO_PA5) /* SPI Peripheral Chip Select 2 */
+#define AT91C_PIO_PA6        ((unsigned int) 1 <<  6) /* Pin Controlled by PA6 */
+#define AT91C_PA6_NPCS3    ((unsigned int) AT91C_PIO_PA6) /* SPI Peripheral Chip Select 3 */
+
+
 #define AT91C_PIO_PA16       ((unsigned int) 1 << 16) /* Pin Controlled by PA16 */
 #define AT91C_PA16_EMDIO    ((unsigned int) AT91C_PIO_PA16) /*  Ethernet MAC Management Data Input/Output */
 #define AT91C_PIO_PA15       ((unsigned int) 1 << 15) /* Pin Controlled by PA15 */
@@ -294,6 +507,8 @@
 #define AT91C_PA8_ETXEN    ((unsigned int) AT91C_PIO_PA8) /*  Ethernet MAC Transmit Enable */
 #define AT91C_PIO_PA7        ((unsigned int) 1 <<  7) /* Pin Controlled by PA7 */
 #define AT91C_PA7_ETXCK_EREFCK ((unsigned int) AT91C_PIO_PA7) /*  Ethernet MAC Transmit Clock/Reference Clock */
+
+#define AT91C_PIO_PB7        ((unsigned int) 1 <<  7) /* Pin Controlled by PB7 */
 #define AT91C_PIO_PB25       ((unsigned int) 1 << 25) /* Pin Controlled by PB25 */
 #define AT91C_PB25_DSR1     ((unsigned int) AT91C_PIO_PB25) /*  USART 1 Data Set ready */
 #define AT91C_PB25_EF100    ((unsigned int) AT91C_PIO_PB25) /*  Ethernet MAC Force 100 Mbits */
@@ -323,7 +538,6 @@
 #define AT91C_PB12_ETX2     ((unsigned int) AT91C_PIO_PB12) /*  Ethernet MAC Transmit Data 2 */
 
 #define AT91C_PIOB_BSR  ((AT91_REG *) 	0xFFFFF674) /* (PIOB) Select B Register */
-#define AT91C_BASE_EMAC      ((AT91PS_EMAC) 	0xFFFBC000) /* (EMAC) Base Address */
 #define AT91C_PIOB_PDR  ((AT91_REG *) 	0xFFFFF604) /* (PIOB) PIO Disable Register */
 
 #define 	AT91C_EBI_CS3A_SMC_SmartMedia       ((unsigned int) 0x1 <<  3) /* (EBI) Chip Select 3 is assigned to the Static Memory Controller and the SmartMedia Logic is activated. */
@@ -335,8 +549,12 @@
 #define AT91C_PIOC_CODR ((AT91_REG *) 	0xFFFFF834) /* (PIOC) Clear Output Data Register */
 #define AT91C_PIOC_PDSR ((AT91_REG *) 	0xFFFFF83C) /* (PIOC) Pin Data Status Register */
 
+#define AT91C_BASE_SPI       ((AT91PS_SPI) 	0xFFFE0000) /* (SPI) Base Address */
+#define AT91C_BASE_EMAC      ((AT91PS_EMAC) 	0xFFFBC000) /* (EMAC) Base Address */
+#define AT91C_BASE_PMC       ((AT91PS_PMC) 	0xFFFFFC00) /* (PMC) Base Address */
 #define AT91C_BASE_TC0       ((AT91PS_TC) 	0xFFFA0000) /* (TC0) Base Address */
 #define AT91C_BASE_DBGU      ((AT91PS_DBGU) 	0xFFFFF200) /* (DBGU) Base Address */
+#define AT91C_BASE_PIOB      ((AT91PS_PIO) 	0xFFFFF600) /* (PIOB) Base Address */
 #define AT91C_BASE_PIOA      ((AT91PS_PIO) 	0xFFFFF400) /* (PIOA) Base Address */
 #define AT91C_EBI_CSA   ((AT91_REG *) 	0xFFFFFF60) /* (EBI) Chip Select Assignment Register */
 #define AT91C_BASE_SMC2      ((AT91PS_SMC2) 	0xFFFFFF70) /* (SMC2) Base Address */
@@ -349,4 +567,5 @@
 #define AT91C_PIOB_PER  ((AT91_REG *) 	0xFFFFF600) /* (PIOB) PIO Enable Register */
 #define AT91C_PIOB_ODR  ((AT91_REG *) 	0xFFFFF614) /* (PIOB) Output Disable Registerr */
 #define AT91C_PIOB_PDSR ((AT91_REG *) 	0xFFFFF63C) /* (PIOB) Pin Data Status Register */
+
 #endif
diff --git a/include/at91rm9200_net.h b/include/at91rm9200_net.h
new file mode 100644
index 0000000..e41fe3c
--- /dev/null
+++ b/include/at91rm9200_net.h
@@ -0,0 +1,59 @@
+/*
+ * Ethernet:	An implementation of the Ethernet Device Driver suite for the
+ *		uClinux 2.0.38 operating system. This Driver has been developed
+ *		for AT75C220 board. 
+ *
+ * NOTE:	The driver is implemented for one MAC
+ *
+ * Version:	@(#)at91rm9200_net.h	1.0.0	01/10/2001
+ *
+ * Authors:	Lineo Inc <www.lineo.com>
+ *
+ *
+ *		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.
+ */
+
+#ifndef AT91RM9200_ETHERNET
+#define AT91RM9200_ETHERNET
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include "dm9161.h"
+
+#define FALSE 0
+#define TRUE 1
+
+
+#define ETHERNET_ADDRESS_SIZE           6
+
+typedef unsigned char UCHAR;
+
+/* Interface to drive the physical layer */
+typedef struct _AT91S_PhyOps
+{
+	unsigned char (*Init)(AT91S_EMAC *pmac);
+	unsigned int (*IsPhyConnected)(AT91S_EMAC  *pmac);
+	unsigned char (*GetLinkSpeed)(AT91S_EMAC *pmac);
+	unsigned char (*AutoNegotiate)(AT91S_EMAC *pmac, int *);
+	
+} AT91S_PhyOps,*AT91PS_PhyOps;
+
+
+#define EMAC_DESC_DONE 0x00000001  /* ownership bit */
+#define EMAC_DESC_WRAP 0x00000002  /* bit for wrap */
+
+/******************  function prototypes **********************/
+
+/* MII functions */
+static void at91rm9200_EmacEnableMDIO(AT91PS_EMAC p_mac);
+static void at91rm9200_EmacDisableMDIO(AT91PS_EMAC p_mac);
+static UCHAR at91rm9200_EmacReadPhy(AT91PS_EMAC p_mac, unsigned char RegisterAddress, unsigned short *pInput);
+static UCHAR at91rm9200_EmacWritePhy(AT91PS_EMAC p_mac, unsigned char RegisterAddress, unsigned short *pOutput);
+void at91rm92000_GetPhyInterface(void );
+
+#endif /* AT91RM9200_ETHERNET */
+
diff --git a/include/configs/at91rm9200dk.h b/include/configs/at91rm9200dk.h
index 6315f0a..e382977 100644
--- a/include/configs/at91rm9200dk.h
+++ b/include/configs/at91rm9200dk.h
@@ -28,12 +28,14 @@
 /* ARM asynchronous clock */
 #define AT91C_MAIN_CLOCK  179712000  /* from 18.432 MHz crystal (18432000 / 4 * 39) */
 #define AT91C_MASTER_CLOCK  59904000  /* peripheral clock (AT91C_MASTER_CLOCK / 3) */
+/* #define AT91C_MASTER_CLOCK  44928000 */  /* peripheral clock (AT91C_MASTER_CLOCK / 4) */
 
-#define CONFIG_AT91RM9200DK	1	/* on an AT91RM9200DK Board      */
+#define CONFIG_AT91RM9200DK	 1	/* on an AT91RM9200DK Board      */
 #undef CONFIG_USE_IRQ			/* we don't need IRQ/FIQ stuff */
 #define CONFIG_CMDLINE_TAG	 1	/* enable passing of ATAGs	*/
 #define CONFIG_SETUP_MEMORY_TAGS 1
 #define CONFIG_INITRD_TAG	 1
+
 /*
  * Size of malloc() pool
  */
@@ -43,24 +45,23 @@
  * Hardware drivers
  */
 
-/*
- * select serial console configuration
- */
-#define CONFIG_SERIAL3          1	/* we use SERIAL 3 */
-
 #undef	CONFIG_HWFLOW			/* don't include RTS/CTS flow control support	*/
 
 #undef	CONFIG_MODEM_SUPPORT		/* disable modem initialization stuff */
 
+#define CONFIG_BOOTDELAY      3  
+/* #define CONFIG_ENV_OVERWRITE  1 */
+
 #define CONFIG_COMMANDS		\
-		       (CONFIG_CMD_DFL	| \
-			CFG_CMD_DHCP	| \
-			CFG_CMD_NAND	)
-/* 			CFG_CMD_EEPROM	| \ might consider these
-			CFG_CMD_I2C	| \
-			CFG_CMD_USB	| \
-			CFG_CMD_MII	| \
-			CFG_CMD_SDRAM	| \ */
+		       ((CONFIG_CMD_DFL	| \
+			CFG_CMD_DHCP ) & \
+                      ~(CFG_CMD_BDI | \
+                        CFG_CMD_IMI | \
+                        CFG_CMD_AUTOSCRIPT | \
+                        CFG_CMD_FPGA | \
+                        CFG_CMD_MISC | \
+                        CFG_CMD_LOADS ))
+                     
 /* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
 #include <cmd_confdefs.h>
 
@@ -101,6 +102,14 @@
 #define CFG_MEMTEST_END   CFG_MEMTEST_START + PHYS_SDRAM_SIZE - 262144
 
 #define CONFIG_DRIVER_ETHER
+#define CONFIG_NET_RETRY_COUNT 20
+
+#define CONFIG_HAS_DATAFLASH	1
+#define CFG_SPI_WRITE_TOUT	CFG_HZ
+#define CFG_MAX_DATAFLASH_BANKS 2
+#define CFG_MAX_DATAFLASH_PAGES 16384
+#define CFG_DATAFLASH_LOGIC_ADDR_CS0	0xC0000000	/* Logical adress for CS0 */
+#define CFG_DATAFLASH_LOGIC_ADDR_CS3	0xD0000000	/* Logical adress for CS3 */
 
 #define PHYS_FLASH_1 0x10000000
 #define PHYS_FLASH_SIZE 0x200000  /* 2 megs main flash */
@@ -110,10 +119,14 @@
 #define CFG_FLASH_ERASE_TOUT	(2*CFG_HZ) /* Timeout for Flash Erase */
 #define CFG_FLASH_WRITE_TOUT	(2*CFG_HZ) /* Timeout for Flash Write */
 #define	CFG_ENV_IS_IN_FLASH	1
-#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0xe000)
-#define CFG_ENV_SIZE 0x2000
+#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0xe000)  /* 0x10000 */
+#define CFG_ENV_SIZE 0x2000  /* 0x8000 */
 #define CFG_LOAD_ADDR 0x21000000  /* default load address */
 
+#define CFG_BOOT_SIZE		0x6000 /* 24 KBytes */
+#define CFG_U_BOOT_BASE 	(PHYS_FLASH_1 + 0x10000)
+#define CFG_U_BOOT_SIZE		0x10000	/* 64 KBytes */
+
 #define CFG_BAUDRATE_TABLE {115200 , 19200, 38400, 57600, 9600 }
 
 #define CFG_PROMPT "Uboot> " /* Monitor Command Prompt */
diff --git a/include/dataflash.h b/include/dataflash.h
new file mode 100644
index 0000000..cc4badf
--- /dev/null
+++ b/include/dataflash.h
@@ -0,0 +1,176 @@
+/*
+ * (C) Copyright 2003
+ * Data Flash Atmel Description File
+ * Author : Hamid Ikdoumi (Atmel)
+ *
+ * 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
+ */
+
+/* File Name		: dataflash.h					*/
+/* Object		: Data Flash Atmel Description File		*/
+/* Translator		:						*/
+/*									*/
+/* 1.0 03/04/01 HI	: Creation					*/
+/* 1.2 20/10/02 FB	: Adapatation Service and Lib v3		*/
+/*----------------------------------------------------------------------*/
+
+#ifndef _DataFlash_h
+#define _DataFlash_h
+
+
+#include <asm/arch/hardware.h>
+#include "config.h"
+
+
+typedef struct {
+	unsigned long base;		/* logical base address for a bank */
+	unsigned long size;		/* total bank size */
+	unsigned long page_count;
+	unsigned long page_size;
+	unsigned long id;		/* device id */
+	unsigned char protect[CFG_MAX_DATAFLASH_PAGES]; /* page protection status */
+} dataflash_info_t;
+
+
+typedef unsigned int AT91S_DataFlashStatus;
+
+/*----------------------------------------------------------------------*/
+/* DataFlash Structures							*/
+/*----------------------------------------------------------------------*/
+
+/*---------------------------------------------*/
+/* DataFlash Descriptor Structure Definition   */
+/*---------------------------------------------*/
+typedef struct _AT91S_DataflashDesc {
+	unsigned char *tx_cmd_pt;
+	unsigned int tx_cmd_size;
+	unsigned char *rx_cmd_pt;
+	unsigned int rx_cmd_size;
+	unsigned char *tx_data_pt;
+	unsigned int tx_data_size;
+	unsigned char *rx_data_pt;
+	unsigned int rx_data_size;
+	volatile unsigned char state;
+	volatile unsigned char DataFlash_state;
+	unsigned char command[8];
+} AT91S_DataflashDesc, *AT91PS_DataflashDesc;
+
+/*---------------------------------------------*/
+/* DataFlash device definition structure       */
+/*---------------------------------------------*/
+typedef struct _AT91S_Dataflash {
+	int pages_number;			/* dataflash page number */
+	int pages_size;				/* dataflash page size */
+	int page_offset;			/* page offset in command */
+	int byte_mask;				/* byte mask in command */
+	int cs;
+} AT91S_DataflashFeatures, *AT91PS_DataflashFeatures;
+
+/*---------------------------------------------*/
+/* DataFlash Structure Definition	       */
+/*---------------------------------------------*/
+typedef struct _AT91S_DataFlash {
+	AT91PS_DataflashDesc pDataFlashDesc;	/* dataflash descriptor */
+	AT91PS_DataflashFeatures pDevice;	/* Pointer on a dataflash features array */
+} AT91S_DataFlash, *AT91PS_DataFlash;
+
+
+
+typedef struct _AT91S_DATAFLASH_INFO {
+
+	AT91S_DataflashDesc Desc;
+	AT91S_DataflashFeatures Device; /* Pointer on a dataflash features array */
+	unsigned long logical_address;
+	unsigned int id;			/* device id */
+	unsigned char protect[CFG_MAX_DATAFLASH_PAGES]; /* page protection status */
+} AT91S_DATAFLASH_INFO, *AT91PS_DATAFLASH_INFO;
+
+
+/*-------------------------------------------------------------------------------------------------*/
+
+#define AT45DB161	0x2c
+#define AT45DB321	0x34
+#define AT45DB642	0x3c
+
+#define AT91C_DATAFLASH_TIMEOUT		10000	/* For AT91F_DataFlashWaitReady */
+
+/* DataFlash return value */
+#define DATAFLASH_BUSY			0x00
+#define DATAFLASH_OK			0x01
+#define DATAFLASH_ERROR			0x02
+#define DATAFLASH_MEMORY_OVERFLOW	0x03
+#define DATAFLASH_BAD_COMMAND		0x04
+#define DATAFLASH_BAD_ADDRESS		0x05
+
+
+/* Driver State */
+#define IDLE		0x0
+#define BUSY		0x1
+#define ERROR		0x2
+
+/* DataFlash Driver State */
+#define GET_STATUS	0x0F
+
+/*-------------------------------------------------------------------------------------------------*/
+/* Command Definition										   */
+/*-------------------------------------------------------------------------------------------------*/
+
+/* READ COMMANDS */
+#define DB_CONTINUOUS_ARRAY_READ	0xE8	/* Continuous array read */
+#define DB_BURST_ARRAY_READ		0xE8	/* Burst array read */
+#define DB_PAGE_READ			0xD2	/* Main memory page read */
+#define DB_BUF1_READ			0xD4	/* Buffer 1 read */
+#define DB_BUF2_READ			0xD6	/* Buffer 2 read */
+#define DB_STATUS			0xD7	/* Status Register */
+
+/* PROGRAM and ERASE COMMANDS */
+#define DB_BUF1_WRITE			0x84	/* Buffer 1 write */
+#define DB_BUF2_WRITE			0x87	/* Buffer 2 write */
+#define DB_BUF1_PAGE_ERASE_PGM		0x83	/* Buffer 1 to main memory page program with built-In erase */
+#define DB_BUF1_PAGE_ERASE_FASTPGM	0x93	/* Buffer 1 to main memory page program with built-In erase, Fast program */
+#define DB_BUF2_PAGE_ERASE_PGM		0x86	/* Buffer 2 to main memory page program with built-In erase */
+#define DB_BUF2_PAGE_ERASE_FASTPGM	0x96	/* Buffer 1 to main memory page program with built-In erase, Fast program */
+#define DB_BUF1_PAGE_PGM		0x88	/* Buffer 1 to main memory page program without built-In erase */
+#define DB_BUF1_PAGE_FASTPGM		0x98	/* Buffer 1 to main memory page program without built-In erase, Fast program */
+#define DB_BUF2_PAGE_PGM		0x89	/* Buffer 2 to main memory page program without built-In erase */
+#define DB_BUF2_PAGE_FASTPGM		0x99	/* Buffer 1 to main memory page program without built-In erase, Fast program */
+#define DB_PAGE_ERASE			0x81	/* Page Erase */
+#define DB_BLOCK_ERASE			0x50	/* Block Erase */
+#define DB_PAGE_PGM_BUF1		0x82	/* Main memory page through buffer 1 */
+#define DB_PAGE_FASTPGM_BUF1		0x92	/* Main memory page through buffer 1, Fast program */
+#define DB_PAGE_PGM_BUF2		0x85	/* Main memory page through buffer 2 */
+#define DB_PAGE_FastPGM_BUF2		0x95	/* Main memory page through buffer 2, Fast program */
+
+/* ADDITIONAL COMMANDS */
+#define DB_PAGE_2_BUF1_TRF		0x53	/* Main memory page to buffer 1 transfert */
+#define DB_PAGE_2_BUF2_TRF		0x55	/* Main memory page to buffer 2 transfert */
+#define DB_PAGE_2_BUF1_CMP		0x60	/* Main memory page to buffer 1 compare */
+#define DB_PAGE_2_BUF2_CMP		0x61	/* Main memory page to buffer 2 compare */
+#define DB_AUTO_PAGE_PGM_BUF1		0x58	/* Auto page rewrite throught buffer 1 */
+#define DB_AUTO_PAGE_PGM_BUF2		0x59	/* Auto page rewrite throught buffer 2 */
+
+/*-------------------------------------------------------------------------------------------------*/
+
+extern int addr_dataflash (unsigned long addr);
+extern int read_dataflash (unsigned long addr, unsigned long size, char *result);
+extern int write_dataflash (unsigned long addr, unsigned long dest, unsigned long size);
+extern void dataflash_print_info (void);
+extern void dataflash_perror (int err);
+
+#endif
diff --git a/include/dm9161.h b/include/dm9161.h
new file mode 100644
index 0000000..6299921
--- /dev/null
+++ b/include/dm9161.h
@@ -0,0 +1,130 @@
+/*
+ * NOTE:	DAVICOM ethernet Physical layer 
+ *
+ * Version:	@(#)DM9161.h	1.0.0	01/10/2001
+ *
+ * Authors:	ATMEL Rousset
+ *
+ *
+ *		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.
+ */
+
+
+// DAVICOM PHYSICAL LAYER TRANSCEIVER DM9161
+
+#define	DM9161_BMCR 		0	// Basic Mode Control Register
+#define DM9161_BMSR		1	// Basic Mode Status Register
+#define DM9161_PHYID1		2	// PHY Idendifier Register 1
+#define DM9161_PHYID2		3	// PHY Idendifier Register 2
+#define DM9161_ANAR		4	// Auto_Negotiation Advertisement Register 
+#define DM9161_ANLPAR		5	// Auto_negotiation Link Partner Ability Register
+#define DM9161_ANER		6	// Auto-negotiation Expansion Register 
+#define DM9161_DSCR		16	// Specified Configuration Register
+#define DM9161_DSCSR		17	// Specified Configuration and Status Register
+#define DM9161_10BTCSR		18	// 10BASE-T Configuration and Satus Register
+#define DM9161_MDINTR		21	// Specified Interrupt Register
+#define DM9161_RECR		22	// Specified Receive Error Counter Register
+#define DM9161_DISCR		23	// Specified Disconnect Counter Register
+#define DM9161_RLSR		24	// Hardware Reset Latch State Register
+
+
+// --Bit definitions: DM9161_BMCR
+#define DM9161_RESET   	         (1 << 15)	// 1= Software Reset; 0=Normal Operation
+#define DM9161_LOOPBACK	         (1 << 14)	// 1=loopback Enabled; 0=Normal Operation
+#define DM9161_SPEED_SELECT      (1 << 13)	// 1=100Mbps; 0=10Mbps
+#define DM9161_AUTONEG	         (1 << 12)
+#define DM9161_POWER_DOWN        (1 << 11)
+#define DM9161_ISOLATE           (1 << 10)	
+#define DM9161_RESTART_AUTONEG   (1 << 9)
+#define DM9161_DUPLEX_MODE       (1 << 8)
+#define DM9161_COLLISION_TEST    (1 << 7)
+
+//--Bit definitions: DM9161_BMSR
+#define DM9161_100BASE_T4        (1 << 15)
+#define DM9161_100BASE_TX_FD     (1 << 14)
+#define DM9161_100BASE_T4_HD     (1 << 13)
+#define DM9161_10BASE_T_FD       (1 << 12)
+#define DM9161_10BASE_T_HD       (1 << 11)
+#define DM9161_MF_PREAMB_SUPPR   (1 << 6)
+#define DM9161_AUTONEG_COMP      (1 << 5)
+#define DM9161_REMOTE_FAULT      (1 << 4)
+#define DM9161_AUTONEG_ABILITY   (1 << 3)
+#define DM9161_LINK_STATUS       (1 << 2)
+#define DM9161_JABBER_DETECT     (1 << 1)
+#define DM9161_EXTEND_CAPAB      (1 << 0)
+
+//--definitions: DM9161_PHYID1
+#define DM9161_PHYID1_OUI	 0x606E
+#define DM9161_LSB_MASK	         0x3F
+
+//--Bit definitions: DM9161_ANAR, DM9161_ANLPAR
+#define DM9161_NP               (1 << 15)
+#define DM9161_ACK              (1 << 14)
+#define DM9161_RF               (1 << 13)
+#define DM9161_FCS              (1 << 10)
+#define DM9161_T4               (1 << 9)
+#define DM9161_TX_FDX           (1 << 8)
+#define DM9161_TX_HDX           (1 << 7)
+#define DM9161_10_FDX           (1 << 6)
+#define DM9161_10_HDX           (1 << 5)
+#define DM9161_AN_IEEE_802_3	0x0001
+
+//--Bit definitions: DM9161_ANER
+#define DM9161_PDF              (1 << 4)
+#define DM9161_LP_NP_ABLE       (1 << 3)
+#define DM9161_NP_ABLE          (1 << 2)
+#define DM9161_PAGE_RX          (1 << 1)
+#define DM9161_LP_AN_ABLE       (1 << 0)
+
+//--Bit definitions: DM9161_DSCR
+#define DM9161_BP4B5B           (1 << 15)
+#define DM9161_BP_SCR           (1 << 14)
+#define DM9161_BP_ALIGN         (1 << 13)
+#define DM9161_BP_ADPOK         (1 << 12)
+#define DM9161_REPEATER         (1 << 11)
+#define DM9161_TX               (1 << 10)
+#define DM9161_RMII_ENABLE      (1 << 8)
+#define DM9161_F_LINK_100       (1 << 7)
+#define DM9161_SPLED_CTL        (1 << 6)
+#define DM9161_COLLED_CTL       (1 << 5)
+#define DM9161_RPDCTR_EN        (1 << 4)
+#define DM9161_SM_RST           (1 << 3)
+#define DM9161_MFP SC           (1 << 2)
+#define DM9161_SLEEP            (1 << 1)
+#define DM9161_RLOUT            (1 << 0)
+
+//--Bit definitions: DM9161_DSCSR
+#define DM9161_100FDX           (1 << 15)
+#define DM9161_100HDX           (1 << 14)
+#define DM9161_10FDX            (1 << 13)
+#define DM9161_10HDX            (1 << 12)
+
+//--Bit definitions: DM9161_10BTCSR
+#define DM9161_LP_EN           (1 << 14)
+#define DM9161_HBE             (1 << 13)
+#define DM9161_SQUELCH         (1 << 12)
+#define DM9161_JABEN           (1 << 11)
+#define DM9161_10BT_SER        (1 << 10)
+#define DM9161_POLR            (1 << 0)
+
+
+//--Bit definitions: DM9161_MDINTR
+#define DM9161_INTR_PEND       (1 << 15)
+#define DM9161_FDX_MASK        (1 << 11)
+#define DM9161_SPD_MASK        (1 << 10)
+#define DM9161_LINK_MASK       (1 << 9)
+#define DM9161_INTR_MASK       (1 << 8)
+#define DM9161_FDX_CHANGE      (1 << 4)
+#define DM9161_SPD_CHANGE      (1 << 3)
+#define DM9161_LINK_CHANGE     (1 << 2)
+#define DM9161_INTR_STATUS     (1 << 0)
+
+
+/******************  function prototypes **********************/
+static unsigned int dm9161_IsPhyConnected(AT91PS_EMAC p_mac);
+static unsigned char  dm9161_GetLinkSpeed(AT91PS_EMAC p_mac);
+static unsigned char dm9161_AutoNegotiate(AT91PS_EMAC p_mac, int *status);
+static unsigned char dm9161_InitPhy(AT91PS_EMAC p_mac);
diff --git a/include/flash.h b/include/flash.h
index 882652d..e594788 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -12,7 +12,7 @@
  *
  * 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
+ * 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
@@ -33,15 +33,15 @@
 	ulong	size;			/* total bank size in bytes		*/
 	ushort	sector_count;		/* number of erase units		*/
 	ulong	flash_id;		/* combined device & manufacturer code	*/
-	ulong	start[CFG_MAX_FLASH_SECT];   /* physical sector start addresses	*/
+	ulong	start[CFG_MAX_FLASH_SECT];   /* physical sector start addresses */
 	uchar	protect[CFG_MAX_FLASH_SECT]; /* sector protection status	*/
 #ifdef CFG_FLASH_CFI
 	uchar	portwidth;		/* the width of the port		*/
 	uchar	chipwidth;		/* the width of the chip		*/
-	ushort  buffer_size;		/* # of bytes in write buffer		*/
+	ushort	buffer_size;		/* # of bytes in write buffer		*/
 	ulong	erase_blk_tout;		/* maximum block erase timeout		*/
 	ulong	write_tout;		/* maximum write timeout		*/
-	ulong   buffer_write_tout;	/* maximum buffer write timeout		*/
+	ulong	buffer_write_tout;	/* maximum buffer write timeout		*/
 
 #endif
 } flash_info_t;
@@ -103,20 +103,20 @@
  * Device IDs
  */
 
-#define AMD_MANUFACT	0x00010001	/* AMD     manuf. ID in D23..D16, D7..D0 */
+#define AMD_MANUFACT	0x00010001	/* AMD	   manuf. ID in D23..D16, D7..D0 */
 #define FUJ_MANUFACT	0x00040004	/* FUJITSU manuf. ID in D23..D16, D7..D0 */
-#define ATM_MANUFACT    0x001F001F      /* ATMEL */
-#define STM_MANUFACT	0x00200020	/* STM (Thomson) manuf. ID in D23.. -"-	*/
-#define SST_MANUFACT	0x00BF00BF	/* SST     manuf. ID in D23..D16, D7..D0 */
-#define MT_MANUFACT	0x00890089	/* MT      manuf. ID in D23..D16, D7..D0 */
+#define ATM_MANUFACT	0x001F001F	/* ATMEL */
+#define STM_MANUFACT	0x00200020	/* STM (Thomson) manuf. ID in D23.. -"- */
+#define SST_MANUFACT	0x00BF00BF	/* SST	   manuf. ID in D23..D16, D7..D0 */
+#define MT_MANUFACT	0x00890089	/* MT	   manuf. ID in D23..D16, D7..D0 */
 #define INTEL_MANUFACT	0x00890089	/* INTEL   manuf. ID in D23..D16, D7..D0 */
-#define	INTEL_ALT_MANU	0x00B000B0	/* alternate INTEL namufacturer ID	*/
+#define INTEL_ALT_MANU	0x00B000B0	/* alternate INTEL namufacturer ID	*/
 #define MX_MANUFACT	0x00C200C2	/* MXIC	   manuf. ID in D23..D16, D7..D0 */
 #define TOSH_MANUFACT	0x00980098	/* TOSHIBA manuf. ID in D23..D16, D7..D0 */
 
 					/* Micron Technologies (INTEL compat.)	*/
 #define MT_ID_28F400_T	0x44704470	/* 28F400B3 ID ( 4 M, top boot sector)	*/
-#define MT_ID_28F400_B	0x44714471	/* 28F400B3 ID ( 4 M, bottom boot sect)	*/
+#define MT_ID_28F400_B	0x44714471	/* 28F400B3 ID ( 4 M, bottom boot sect) */
 
 #define AMD_ID_LV040B	0x4F		/* 29LV040B ID				*/
 					/* 4 Mbit, 512K x 8,			*/
@@ -125,7 +125,7 @@
 #define AMD_ID_F040B	0xA4		/* 29F040B ID				*/
 					/* 4 Mbit, 512K x 8,			*/
 					/* 8 64K x 8 uniform sectors		*/
-#define STM_ID_M29W040B	0xE3		/* M29W040B ID 				*/
+#define STM_ID_M29W040B 0xE3		/* M29W040B ID				*/
 					/* 4 Mbit, 512K x 8,			*/
 					/* 8 64K x 8 uniform sectors		*/
 #define AMD_ID_F080B	0xD5		/* 29F080  ID  ( 1 M)			*/
@@ -137,49 +137,50 @@
 #define AMD_ID_LV016B	0xc8		/* 29LV016 ID  ( 2 M x 8)		*/
 
 #define AMD_ID_LV400T	0x22B922B9	/* 29LV400T ID ( 4 M, top boot sector)	*/
-#define AMD_ID_LV400B	0x22BA22BA	/* 29LV400B ID ( 4 M, bottom boot sect)	*/
+#define AMD_ID_LV400B	0x22BA22BA	/* 29LV400B ID ( 4 M, bottom boot sect) */
 
 #define AMD_ID_LV033C	0xA3		/* 29LV033C ID ( 4M x 8 )		*/
 
 #define AMD_ID_LV800T	0x22DA22DA	/* 29LV800T ID ( 8 M, top boot sector)	*/
-#define AMD_ID_LV800B	0x225B225B	/* 29LV800B ID ( 8 M, bottom boot sect)	*/
+#define AMD_ID_LV800B	0x225B225B	/* 29LV800B ID ( 8 M, bottom boot sect) */
 
 #define AMD_ID_LV160T	0x22C422C4	/* 29LV160T ID (16 M, top boot sector)	*/
-#define AMD_ID_LV160B	0x22492249	/* 29LV160B ID (16 M, bottom boot sect)	*/
+#define AMD_ID_LV160B	0x22492249	/* 29LV160B ID (16 M, bottom boot sect) */
 
 #define AMD_ID_LV320T	0x22F622F6	/* 29LV320T ID (32 M, top boot sector)	*/
-#define AMD_ID_LV320B	0x22F922F9	/* 29LV320B ID (32 M, bottom boot sect)	*/
+#define AMD_ID_LV320B	0x22F922F9	/* 29LV320B ID (32 M, bottom boot sect) */
 
 #define AMD_ID_DL322T	0x22552255	/* 29DL322T ID (32 M, top boot sector)	*/
-#define AMD_ID_DL322B	0x22562256	/* 29DL322B ID (32 M, bottom boot sect)	*/
+#define AMD_ID_DL322B	0x22562256	/* 29DL322B ID (32 M, bottom boot sect) */
 #define AMD_ID_DL323T	0x22502250	/* 29DL323T ID (32 M, top boot sector)	*/
-#define AMD_ID_DL323B	0x22532253	/* 29DL323B ID (32 M, bottom boot sect)	*/
+#define AMD_ID_DL323B	0x22532253	/* 29DL323B ID (32 M, bottom boot sect) */
 #define AMD_ID_DL324T	0x225C225C	/* 29DL324T ID (32 M, top boot sector)	*/
 #define AMD_ID_DL324B	0x225F225F	/* 29DL324B ID (32 M, bottom boot sect) */
 
 #define AMD_ID_DL640	0x227E227E	/* 29DL640D ID (64 M, dual boot sectors)*/
-#define AMD_ID_MIRROR	0x227E227E	/* 1st ID word for MirrorBit family */ 
-#define AMD_ID_LV128U_2	0x22122212	/* 2d ID word for AM29LV128M at 0x38 */
-#define AMD_ID_LV128U_3	0x22002200	/* 3d ID word for AM29LV128M at 0x3c */
+#define AMD_ID_MIRROR	0x227E227E	/* 1st ID word for MirrorBit family */
+#define AMD_ID_LV128U_2 0x22122212	/* 2d ID word for AM29LV128M at 0x38 */
+#define AMD_ID_LV128U_3 0x22002200	/* 3d ID word for AM29LV128M at 0x3c */
 
 #define AMD_ID_LV640U	0x22D722D7	/* 29LV640U ID (64 M, uniform sectors)	*/
 
-#define ATM_ID_BV1614   0x000000C0      /* 49BV1614 ID */
+#define ATM_ID_BV1614	0x000000C0	/* 49BV1614 ID */
+#define ATM_ID_BV1614A	0x000000C8	/* 49BV1614A ID */
 
-#define FUJI_ID_29F800BA  0x22582258   /* MBM29F800BA ID  (8M) */
-#define FUJI_ID_29F800TA  0x22D622D6   /* MBM29F800TA ID  (8M) */
+#define FUJI_ID_29F800BA  0x22582258	/* MBM29F800BA ID  (8M) */
+#define FUJI_ID_29F800TA  0x22D622D6	/* MBM29F800TA ID  (8M) */
 
-#define SST_ID_xF200A	0x27892789	/* 39xF200A ID ( 2M = 128K x 16	)	*/
-#define SST_ID_xF400A	0x27802780	/* 39xF400A ID ( 4M = 256K x 16	)	*/
-#define SST_ID_xF800A	0x27812781	/* 39xF800A ID ( 8M = 512K x 16	)	*/
-#define SST_ID_xF160A	0x27822782	/* 39xF800A ID (16M =   1M x 16 )	*/
+#define SST_ID_xF200A	0x27892789	/* 39xF200A ID ( 2M = 128K x 16 )	*/
+#define SST_ID_xF400A	0x27802780	/* 39xF400A ID ( 4M = 256K x 16 )	*/
+#define SST_ID_xF800A	0x27812781	/* 39xF800A ID ( 8M = 512K x 16 )	*/
+#define SST_ID_xF160A	0x27822782	/* 39xF800A ID (16M =	1M x 16 )	*/
 
-#define STM_ID_F040B	0xE2		/* M29F040B ID ( 4M = 512K x 8  )	*/
+#define STM_ID_F040B	0xE2		/* M29F040B ID ( 4M = 512K x 8	)	*/
 					/* 8 64K x 8 uniform sectors		*/
 
-#define STM_ID_x800AB	0x005B005B	/* M29W800AB ID (8M = 512K x 16	)	*/
-#define STM_ID_29W320DT	0x22CA22CA	/* M29W320DT ID (32 M, top boot sector)	*/
-#define STM_ID_29W320DB	0x22CB22CB	/* M29W320DB ID (32 M, bottom boot sect)	*/
+#define STM_ID_x800AB	0x005B005B	/* M29W800AB ID (8M = 512K x 16 )	*/
+#define STM_ID_29W320DT 0x22CA22CA	/* M29W320DT ID (32 M, top boot sector) */
+#define STM_ID_29W320DB 0x22CB22CB	/* M29W320DB ID (32 M, bottom boot sect)	*/
 #define STM_ID_29W040B	0x00E300E3	/* M29W040B ID (4M = 512K x 8)	*/
 
 #define INTEL_ID_28F016S    0x66a066a0	/* 28F016S[VS] ID (16M = 512k x 16)	*/
@@ -202,7 +203,7 @@
 #define INTEL_ID_28F640C3T  0x88CC88CC	/*  64M = 4M x 16 top boot sector	*/
 #define INTEL_ID_28F640C3B  0x88CD88CD	/*  64M = 4M x 16 bottom boot sector	*/
 
-#define INTEL_ID_28F128J3   0x89189818  /*  16M = 8M x 16 x 128	*/
+#define INTEL_ID_28F128J3   0x89189818	/*  16M = 8M x 16 x 128 */
 #define INTEL_ID_28F640J5   0x00150015	/*  64M = 128K x  64			*/
 #define INTEL_ID_28F320J3A  0x00160016	/*  32M = 128K x  32			*/
 #define INTEL_ID_28F640J3A  0x00170017	/*  64M = 128K x  64			*/
@@ -217,8 +218,8 @@
 #define SHARP_ID_28F008SC   0xA6A6A6A6	/* LH28F008SCT-L12 1Mx8, 16 64k blocks	*/
 					/* LH28F008SCR-L85 1Mx8, 16 64k blocks	*/
 
-#define TOSH_ID_FVT160	0xC2		/* TC58FVT160 ID (16 M, top )           */
-#define TOSH_ID_FVB160	0x43		/* TC58FVT160 ID (16 M, bottom )        */
+#define TOSH_ID_FVT160	0xC2		/* TC58FVT160 ID (16 M, top )		*/
+#define TOSH_ID_FVB160	0x43		/* TC58FVT160 ID (16 M, bottom )	*/
 
 /*-----------------------------------------------------------------------
  * Internal FLASH identification codes
@@ -226,25 +227,25 @@
  * Be careful when adding new type! Odd numbers are "bottom boot sector" types!
  */
 
-#define FLASH_AM040	0x0001		/* AMD Am29F040B, Am29LV040B            */
-					/* Bright Micro BM29F040                */
-					/* Fujitsu MBM29F040A                   */
-					/* STM M29W040B                         */
-					/* SGS Thomson M29F040B                 */
-					/* 8 64K x 8 uniform sectors            */
+#define FLASH_AM040	0x0001		/* AMD Am29F040B, Am29LV040B		*/
+					/* Bright Micro BM29F040		*/
+					/* Fujitsu MBM29F040A			*/
+					/* STM M29W040B				*/
+					/* SGS Thomson M29F040B			*/
+					/* 8 64K x 8 uniform sectors		*/
 #define FLASH_AM400T	0x0002		/* AMD AM29LV400			*/
 #define FLASH_AM400B	0x0003
 #define FLASH_AM800T	0x0004		/* AMD AM29LV800			*/
 #define FLASH_AM800B	0x0005
 #define FLASH_AM116DT	0x0026		/* AMD AM29LV116DT (2Mx8bit) */
 #define FLASH_AM160T	0x0006		/* AMD AM29LV160			*/
-#define FLASH_AM160LV	0x0046		/* AMD29LV160DB (2M = 2Mx8bit )	*/
+#define FLASH_AM160LV	0x0046		/* AMD29LV160DB (2M = 2Mx8bit ) */
 #define FLASH_AM160B	0x0007
 #define FLASH_AM320T	0x0008		/* AMD AM29LV320			*/
 #define FLASH_AM320B	0x0009
 
-#define FLASH_AM080	0x000A		/* AMD Am29F080B                        */
-					/* 16 64K x 8 uniform sectors           */
+#define FLASH_AM080	0x000A		/* AMD Am29F080B			*/
+					/* 16 64K x 8 uniform sectors		*/
 
 #define FLASH_AMDL322T	0x0010		/* AMD AM29DL322			*/
 #define FLASH_AMDL322B	0x0011
@@ -262,8 +263,8 @@
 #define FLASH_SST160A	0x0046		/* SST 39xF160A ID ( 16M =   1M x 16 )	*/
 
 #define FLASH_STM800AB	0x0051		/* STM M29WF800AB  (  8M = 512K x 16 )	*/
-#define FLASH_STMW320DT	0x0052		/* STM M29W320DT   (32 M, top boot sector)	*/
-#define FLASH_STMW320DB	0x0053		/* STM M29W320DB   (32 M, bottom boot sect)*/
+#define FLASH_STMW320DT 0x0052		/* STM M29W320DT   (32 M, top boot sector)	*/
+#define FLASH_STMW320DB 0x0053		/* STM M29W320DB   (32 M, bottom boot sect)*/
 #define FLASH_STM320DB	0x00CB		/* STM M29W320DB (4M = 64K x 64, bottom)*/
 #define FLASH_STM800DT	0x00D7		/* STM M29W800DT (1M = 64K x 16, top)	*/
 #define FLASH_STM800DB	0x005B		/* STM M29W800DB (1M = 64K x 16, bottom)*/
@@ -287,26 +288,26 @@
 #define FLASH_28F008S5	0x0080		/* Intel 28F008S5  (  1M =  64K x 16 )	*/
 #define FLASH_28F016SV	0x0081		/* Intel 28F016SV  ( 16M = 512k x 32 )	*/
 #define FLASH_28F800_B	0x0083		/* Intel E28F800B  (  1M = ? )		*/
-#define FLASH_AM29F800B	0x0084		/* AMD Am29F800BB  (  1M = ? )		*/
+#define FLASH_AM29F800B 0x0084		/* AMD Am29F800BB  (  1M = ? )		*/
 #define FLASH_28F320J5	0x0085		/* Intel 28F320J5  (  4M = 128K x 32 )	*/
 #define FLASH_28F160S3	0x0086		/* Intel 28F160S3  ( 16M = 512K x 32 )	*/
 #define FLASH_28F320S3	0x0088		/* Intel 28F320S3  ( 32M = 512K x 64 )	*/
 #define FLASH_AM640U	0x0090		/* AMD Am29LV640U  ( 64M = 4M x 16 )	*/
 #define FLASH_AM033C	0x0091		/* AMD AM29LV033   ( 32M = 4M x 8 )	*/
-#define FLASH_LH28F016SCT 0x0092	/* Sharp 28F016SCT ( 8 Meg Flash SIMM )	*/
-#define FLASH_28F160F3B	0x0093		/* Intel 28F160F3B ( 16M = 1M x 16 )	*/
+#define FLASH_LH28F016SCT 0x0092	/* Sharp 28F016SCT ( 8 Meg Flash SIMM ) */
+#define FLASH_28F160F3B 0x0093		/* Intel 28F160F3B ( 16M = 1M x 16 )	*/
 
-#define FLASH_28F640J5  0x0099		/* INTEL 28F640J5  ( 64M = 128K x  64)	*/
+#define FLASH_28F640J5	0x0099		/* INTEL 28F640J5  ( 64M = 128K x  64)	*/
 
-#define FLASH_28F800C3T	0x009A		/* Intel 28F800C3T (  8M = 512K x 16 )	*/
-#define FLASH_28F800C3B	0x009B		/* Intel 28F800C3B (  8M = 512K x 16 )	*/
-#define FLASH_28F160C3T	0x009C		/* Intel 28F160C3T ( 16M = 1M x 16 )	*/
-#define FLASH_28F160C3B	0x009D		/* Intel 28F160C3B ( 16M = 1M x 16 )	*/
-#define FLASH_28F320C3T	0x009E		/* Intel 28F320C3T ( 32M = 2M x 16 )	*/
-#define FLASH_28F320C3B	0x009F		/* Intel 28F320C3B ( 32M = 2M x 16 )	*/
-#define FLASH_28F640C3T	0x00A0		/* Intel 28F640C3T ( 64M = 4M x 16 )	*/
-#define FLASH_28F640C3B	0x00A1		/* Intel 28F640C3B ( 64M = 4M x 16 )	*/
-#define FLASH_AMLV128U		0x00A2		/* AMD 29LV128M    ( 128M = 8M x 16 )	*/
+#define FLASH_28F800C3T 0x009A		/* Intel 28F800C3T (  8M = 512K x 16 )	*/
+#define FLASH_28F800C3B 0x009B		/* Intel 28F800C3B (  8M = 512K x 16 )	*/
+#define FLASH_28F160C3T 0x009C		/* Intel 28F160C3T ( 16M = 1M x 16 )	*/
+#define FLASH_28F160C3B 0x009D		/* Intel 28F160C3B ( 16M = 1M x 16 )	*/
+#define FLASH_28F320C3T 0x009E		/* Intel 28F320C3T ( 32M = 2M x 16 )	*/
+#define FLASH_28F320C3B 0x009F		/* Intel 28F320C3B ( 32M = 2M x 16 )	*/
+#define FLASH_28F640C3T 0x00A0		/* Intel 28F640C3T ( 64M = 4M x 16 )	*/
+#define FLASH_28F640C3B 0x00A1		/* Intel 28F640C3B ( 64M = 4M x 16 )	*/
+#define FLASH_AMLV128U		0x00A2		/* AMD 29LV128M	   ( 128M = 8M x 16 )	*/
 
 #define FLASH_UNKNOWN	0xFFFF		/* unknown flash type			*/
 
@@ -318,14 +319,14 @@
 #define FLASH_MAN_BM	0x00020000	/* Bright Microelectronics		*/
 #define FLASH_MAN_MX	0x00030000	/* MXIC					*/
 #define FLASH_MAN_STM	0x00040000
-#define FLASH_MAN_TOSH	0x00050000	/* Toshiba                		*/
+#define FLASH_MAN_TOSH	0x00050000	/* Toshiba				*/
 #define FLASH_MAN_SST	0x00100000
-#define FLASH_MAN_INTEL	0x00300000
+#define FLASH_MAN_INTEL 0x00300000
 #define FLASH_MAN_MT	0x00400000
-#define FLASH_MAN_SHARP	0x00500000
+#define FLASH_MAN_SHARP 0x00500000
 
 
-#define FLASH_TYPEMASK	0x0000FFFF	/* extract FLASH type   information	*/
+#define FLASH_TYPEMASK	0x0000FFFF	/* extract FLASH type	information	*/
 #define FLASH_VENDMASK	0xFFFF0000	/* extract FLASH vendor information	*/
 
 #define FLASH_AMD_COMP	0x000FFFFF	/* Up to this ID, FLASH is compatible	*/
diff --git a/lib_arm/armlinux.c b/lib_arm/armlinux.c
index 2fb8db8..0305803 100644
--- a/lib_arm/armlinux.c
+++ b/lib_arm/armlinux.c
@@ -27,6 +27,9 @@
 #include <image.h>
 #include <zlib.h>
 #include <asm/byteorder.h>
+#ifdef CONFIG_HAS_DATAFLASH
+#include <dataflash.h>
+#endif
 
 #include <asm/setup.h>
 #define tag_size(type)  ((sizeof(struct tag_header) + sizeof(struct type)) >> 2)
@@ -94,6 +97,11 @@
 	printf ("## Loading Ramdisk Image at %08lx ...\n", addr);
 
 	/* Copy header so we can blank CRC field for re-calculation */
+#ifdef CONFIG_HAS_DATAFLASH
+	if (addr_dataflash(addr)){
+		read_dataflash(addr, sizeof(image_header_t), (char *)&header);
+	} else
+#endif	
 	memcpy (&header, (char *)addr, sizeof(image_header_t));
 
 	if (ntohl(hdr->ih_magic) != IH_MAGIC) {
@@ -121,6 +129,13 @@
 	data = addr + sizeof(image_header_t);
 	len  = ntohl(hdr->ih_size);
 
+#ifdef CONFIG_HAS_DATAFLASH
+	if (addr_dataflash(addr)){
+		read_dataflash(data, len, (char *)CFG_LOAD_ADDR);
+		data = CFG_LOAD_ADDR;
+	}
+#endif
+
 	if (verify) {
 	    ulong csum = 0;
 
diff --git a/lib_arm/board.c b/lib_arm/board.c
index af6af14..37d4d9f 100644
--- a/lib_arm/board.c
+++ b/lib_arm/board.c
@@ -37,6 +37,11 @@
 
 ulong monitor_flash_len;
 
+#ifdef CONFIG_HAS_DATAFLASH
+extern int  AT91F_DataflashInit(void);
+extern void dataflash_print_info(void);
+#endif
+
 const char version_string[] =
 	U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")";
 
@@ -242,6 +247,11 @@
 	nand_init();		/* go init the NAND */
 #endif
 
+#ifdef CONFIG_HAS_DATAFLASH
+	AT91F_DataflashInit();
+	dataflash_print_info();
+#endif
+
 	/* initialize environment */
 	env_relocate ();