This is the mail archive of the ecos-patches@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Ethernet device driver for ARM NET+50


This patch contains an ethernet device driver for the ARM NET+50.

Regards
Harald



diff -Naur
ecos/packages/devs/eth/arm/netarm/current/cdl/netarm_eth_driver.cdl
my_ecos/packages/devs/eth/arm/netarm/current/cdl/netarm_eth_driver.cdl
--- ecos/packages/devs/eth/arm/netarm/current/cdl/netarm_eth_driver.cdl
1970-01-01 01:00:00.000000000 +0100
+++
my_ecos/packages/devs/eth/arm/netarm/current/cdl/netarm_eth_driver.cdl
2004-11-30 10:45:17.405241500 +0100
@@ -0,0 +1,124 @@
+# ====================================================================
+#
+#	netarm_eth_driver.cdl
+#
+#	Ethernet driver
+#	NET+ARM ethernet interface
+#
+# ====================================================================
+#####ECOSGPLCOPYRIGHTBEGIN####
+## -------------------------------------------
+## This file is part of eCos, the Embedded Configurable Operating
System.
+## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+##
+## eCos 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 or (at your option) any later
version.
+##
+## eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
+## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+##
+## As a special exception, if other files instantiate templates or use
macros
+## or inline functions from this file, or you compile this file and
link it
+## with other works to produce a work based on this file, this file
does not
+## by itself cause the resulting work to be covered by the GNU General
Public
+## License. However the source code for this file must still be made
available
+## in accordance with section (3) of the GNU General Public License.
+##
+## This exception does not invalidate any other reasons why a work
based on
+## this file might be covered by the GNU General Public License.
+##
+## Alternative licenses for eCos may be arranged by contacting Red Hat,
Inc.
+## at http://sources.redhat.com/ecos/ecos-license/
+## -------------------------------------------
+#####ECOSGPLCOPYRIGHTEND####
+# ====================================================================
+######DESCRIPTIONBEGIN####
+#
+# Author(s):      Harald Brandl (harald.brandl@fh-joanneum.at)
+# Original data:
+# Contributors:	  
+# Date:           01.08.2004
+#
+#####DESCRIPTIONEND####
+#
+# ====================================================================
+
+cdl_package CYGPKG_DEVS_ETH_ARM_NETARM {
+    display       "NetSilicon board ethernet driver"
+    description   "Ethernet driver for NET+ARM."
+
+    parent        CYGPKG_IO_ETH_DRIVERS
+    active_if	  CYGPKG_IO_ETH_DRIVERS
+
+    include_dir   cyg/io/eth
+    
+    compile -library=libextras.a MII.c netarm_eth_drv.c
+
+    define_proc {
+        puts $::cdl_system_header "/***** ethernet driver proc output
start *****/"
+        puts $::cdl_system_header "#define CYGDAT_DEVS_ETH_NETARM_CFG
<pkgconf/devs_eth_arm_netarm.h>"
+        puts $::cdl_system_header "/*****  ethernet driver proc output
end  *****/"
+    }
+
+    cdl_component CYGPKG_DEVS_ETH_ARM_NETARM_ETH0 {
+        display       "Ethernet port 0 driver"
+        flavor        bool
+        default_value 1
+
+        implements CYGHWR_NET_DRIVERS
+        implements CYGHWR_NET_DRIVER_ETH0
+
+        cdl_option CYGDAT_DEVS_ETH_ARM_NETARM_ETH0_NAME {
+            display       "Device name for the ETH0 ethernet port 0
driver"
+            flavor        data
+            default_value {"\"eth0\""}
+            description   "
+                This option sets the name of the ethernet device for
the
+                netarm ethernet port 0."
+        }
+
+        cdl_component CYGSEM_DEVS_ETH_ARM_NETARM_ETH0_SET_ESA {
+            display       "Set the ethernet station address"
+            flavor        bool
+	    default_value 0
+            description   "Enabling this option will allow the ethernet
+            station address to be forced to the value set by the
+            configuration.  This may be required if the hardware does
+            not include a serial EEPROM for the ESA."
+            
+            cdl_option CYGDAT_DEVS_ETH_ARM_NETARM_ETH0_ESA {
+                display       "The ethernet station address"
+                flavor        data
+                default_value {"{0x00, 0x40, 0xaf, 0x77, 0xe0, 0x80}"}
+                description   "The ethernet station address"
+            }
+        }
+        
+        cdl_component CYGPKG_DEVS_ETH_ARM_NETARM_OPTIONS {
+	    display "NETARM ethernet driver build options"
+	    flavor  none
+	    no_define
+	
+	    cdl_option CYGPKG_DEVS_ETH_ARM_NETARM_CFLAGS_ADD {
+	        display "Additional compiler flags"
+	        flavor  data
+	        no_define
+	        default_value { "-D_KERNEL -D__ECOS" }
+	        description   "
+	            This option modifies the set of compiler flags for
+	            building the NETARM ethernet driver
+	            package. These flags are used in addition to the set
of
+	            global flags."
+	    }
+        }
+    }
+}
+
+# EOF netarm_eth_driver.cdl
diff -Naur ecos/packages/devs/eth/arm/netarm/current/include/MII.h
my_ecos/packages/devs/eth/arm/netarm/current/include/MII.h
--- ecos/packages/devs/eth/arm/netarm/current/include/MII.h
1970-01-01 01:00:00.000000000 +0100
+++ my_ecos/packages/devs/eth/arm/netarm/current/include/MII.h
2004-11-27 16:04:57.797795200 +0100
@@ -0,0 +1,31 @@
+#ifndef __MII__
+#define __MII__
+
+// ====================================================================
+//
+//      MII.h
+//
+//      PHY chip configuration
+//
+// ====================================================================
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           Harald Brandl (harald.brandl@fh-joanneum.at)
+// Contributors:        Harald Brandl
+// Date:        		01.08.2004
+// Purpose:     		Functions for PHY control
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+
+void mii_reset(void);
+void mii_set_speed (cyg_bool speed, cyg_bool duplex);
+cyg_bool mii_check_speed(void);
+cyg_bool mii_check_duplex(void);
+cyg_bool mii_negotiate(void);
+
+#endif
diff -Naur ecos/packages/devs/eth/arm/netarm/current/include/eth_regs.h
my_ecos/packages/devs/eth/arm/netarm/current/include/eth_regs.h
--- ecos/packages/devs/eth/arm/netarm/current/include/eth_regs.h
1970-01-01 01:00:00.000000000 +0100
+++ my_ecos/packages/devs/eth/arm/netarm/current/include/eth_regs.h
2004-11-27 16:19:34.738774400 +0100
@@ -0,0 +1,94 @@
+#ifndef __ethregs__
+#define __ethregs__
+
+// ====================================================================
+//
+//      eth_regs.h
+//
+//      Address mappings for ethernet and DMA controller registers
+//
+// ====================================================================
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           Harald Brandl (harald.brandl@fh-joanneum.at)
+// Contributors:        Harald Brandl
+// Date:        		01.08.2004
+// Purpose:     		Ethernet and DMA controller registers
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+// Ethernet
+
+#define EthGenCR 			 *(unsigned long *)0xff800000
+#define EthGenSR 			 *(unsigned long *)0xff800004
+#define EthFIFODR			 *(unsigned long *)0xff800008
+#define EthFIFODRkickoff	 *(unsigned long *)0xff80000c
+#define EthTxSR 			 *(unsigned long *)0xff800010
+#define EthRxSR 			 *(unsigned long *)0xff800014
+#define MACCR 				 *(unsigned long *)0xff800400
+#define MACTR 				 *(unsigned long *)0xff800404
+#define PCSCR 				 *(unsigned long *)0xff800408
+#define PCSTR 				 *(unsigned long *)0xff80040c
+#define STLCR 				 *(unsigned long *)0xff800410
+#define STLTR 				 *(unsigned long *)0xff800414
+#define BtBIPGGapTimerR		 *(unsigned long *)0xff800440
+#define NonBtBIPGGapTimerR	 *(unsigned long *)0xff800444
+#define CollWinR 			 *(unsigned long *)0xff800448
+#define TxPNCR 				 *(unsigned long
*)0xff800460
+#define TxBCR 				 *(unsigned long *)0xff800464
+#define ReTxBCR 			 *(unsigned long *)0xff800468
+#define TxRNG 				 *(unsigned long *)0xff80046c
+#define TxMRN 				 *(unsigned long *)0xff800470
+#define TxCDec 				 *(unsigned long
*)0xff800474
+#define TOTxC 				 *(unsigned long *)0xff800478
+#define RxBC 				 *(unsigned long *)0xff800480
+#define RxCDec 				 *(unsigned long
*)0xff800484
+#define TORxC 				 *(unsigned long *)0xff800488
+#define LnFC 				 *(unsigned long *)0xff8004c0
+#define JC10M 				 *(unsigned long *)0xff800500
+#define LoCC10M 			 *(unsigned long *)0xff800504
+#define MIICR 				 *(unsigned long *)0xff800540
+#define MIIAR 				 *(unsigned long *)0xff800544
+#define MIIWDR 				 *(unsigned long
*)0xff800548
+#define MIIRDR 				 *(unsigned long
*)0xff80054c
+#define MIIIR 				 *(unsigned long *)0xff800550
+#define CRCEC 				 *(unsigned long *)0xff800580
+#define AEC 				 *(unsigned long *)0xff800584
+#define CEC 				 *(unsigned long *)0xff800588
+#define LFC 				 *(unsigned long *)0xff80058c
+#define SFC 				 *(unsigned long *)0xff800590
+#define LCC 				 *(unsigned long *)0xff800594
+#define EDC 				 *(unsigned long *)0xff800598
+#define MCC 				 *(unsigned long *)0xff80059c
+#define SAFR 				 *(unsigned long *)0xff8005c0
+#define SAR1 				 *(unsigned long *)0xff8005c4
+#define SAR2 				 *(unsigned long *)0xff8005c8
+#define SAR3 				 *(unsigned long *)0xff8005cc
+#define SAMHT1 				 *(unsigned long
*)0xff8005d0
+#define SAMHT2 				 *(unsigned long
*)0xff8005d4
+#define SAMHT3 				 *(unsigned long
*)0xff8005d8
+#define SAMHT4 				 *(unsigned long
*)0xff8005dc
+
+// DMA
+
+#define DMA1A_BDP	*(unsigned long *)0xff900000
+#define DMA1A_CR	*(unsigned long *)0xff900010
+#define DMA1A_SR	*(unsigned long *)0xff900014
+#define DMA1B_BDP	*(unsigned long *)0xff900020
+#define DMA1B_CR	*(unsigned long *)0xff900030
+#define DMA1B_SR	*(unsigned long *)0xff900034
+#define DMA1C_BDP	*(unsigned long *)0xff900040
+#define DMA1C_CR	*(unsigned long *)0xff900050
+#define DMA1C_SR	*(unsigned long *)0xff900054
+#define DMA1D_BDP	*(unsigned long *)0xff900060
+#define DMA1D_CR	*(unsigned long *)0xff900070
+#define DMA1D_SR	*(unsigned long *)0xff900074
+#define DMA2_BDP	*(unsigned long *)0xff900080
+#define DMA2_CR		*(unsigned long *)0xff900090
+#define DMA2_SR		*(unsigned long *)0xff900094
+
+#endif
diff -Naur
ecos/packages/devs/eth/arm/netarm/current/include/netarm_eth_drv.h
my_ecos/packages/devs/eth/arm/netarm/current/include/netarm_eth_drv.h
--- ecos/packages/devs/eth/arm/netarm/current/include/netarm_eth_drv.h
1970-01-01 01:00:00.000000000 +0100
+++
my_ecos/packages/devs/eth/arm/netarm/current/include/netarm_eth_drv.h
2004-11-27 16:03:01.019876800 +0100
@@ -0,0 +1,62 @@
+#ifndef __netarm__
+#define __netarm__
+
+// ====================================================================
+//
+//      netarm_eth_drv.h
+//
+//      Device I/O - Description of NET+ARM ethernet hardware functions
+//		and data structures
+//
+// ====================================================================
+// ====================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):           Harald Brandl (harald.brandl@fh-joanneum.at)
+// Contributors:        Harald Brandl
+// Date:        		01.08.2004
+// Purpose:     		Internal interfaces and data structures
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+// ====================================================================
+
+
+#define MaxKeys 20
+
+typedef struct
+{
+	unsigned char *RxBuffer;
+	unsigned short key_head, key_tail;
+	unsigned long KeyBuffer[MaxKeys];
+}private_data_t;
+
+typedef struct
+{
+	unsigned W: 1;
+	unsigned I: 1;
+	unsigned L: 1;
+	unsigned BufferPointer: 29;
+	unsigned : 16;
+	unsigned F: 1;
+	unsigned BufferLen: 15;
+}BDP_t;
+
+
+static bool netarm_init(struct cyg_netdevtab_entry *tab);
+
+static void netarm_recv(struct eth_drv_sc *sc, struct eth_drv_sg
*sg_list, int sg_len);
+static void netarm_deliver(struct eth_drv_sc *sc);
+static int netarm_can_send(struct eth_drv_sc *sc);
+static void netarm_send(
+	struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
int total_len, unsigned long key);
+static void netarm_start(struct eth_drv_sc *sc, unsigned char *enaddr,
int flags);
+static void netarm_stop(struct eth_drv_sc *sc);
+static int netarm_control(struct eth_drv_sc *sc, unsigned long key,
void *data, int len);
+static void netarm_poll(struct eth_drv_sc *sc);
+static int netarm_int_vector(struct eth_drv_sc *sc);
+
+static void SetMAC(unsigned char *esa);
+
+#endif
diff -Naur ecos/packages/devs/eth/arm/netarm/current/src/MII.c
my_ecos/packages/devs/eth/arm/netarm/current/src/MII.c
--- ecos/packages/devs/eth/arm/netarm/current/src/MII.c	1970-01-01
01:00:00.000000000 +0100
+++ my_ecos/packages/devs/eth/arm/netarm/current/src/MII.c
2004-11-27 16:13:14.031344000 +0100
@@ -0,0 +1,201 @@
+//=====================================================================
=====
+//
+//      MII.c
+//
+//      NetSilion NET+ARM PHY chip configuration
+//
+//=====================================================================
=====
+//=====================================================================
=====
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   	Harald Brandl (harald.brandl@fh-joanneum.at)
+// Contributors:  	Harald Brandl
+// Date:        	01.08.2004
+// Purpose:     	PHY chip configuration
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//=====================================================================
=====
+
+#include <stdio.h>
+#include <cyg/io/eth/eth_regs.h>
+#include <pkgconf/devs_eth_arm_netarm.h>
+#include <cyg/hal/hal_diag.h>
+
+
+#define PHYS(_i_) (0x800 | _i_)
+
+#define SysReg (unsigned int*)0xffb00004		// System Status
Register
+
+
+
+/*  Function: void mii_poll_busy (void)
+ *
+ *  Description:
+ *     This routine is responsible for waiting for the current PHY
+ *     operation to complete.
+ *
+ *  Parameters:
+ *     none
+ */
+
+void mii_poll_busy(void)
+{
+    /* check to see if PHY is busy with read or write */
+    while (MIIIR & 1)
+    	HAL_DELAY_US(1);
+}
+
+/*  Function: void mii_reset (void)
+ *
+ *  Description:
+ *
+ *       This routine resets the PHY.
+ *
+ *  Return Values:
+ *      none
+ */
+
+void mii_reset(void)
+{
+	MIIAR = PHYS(0);	// select command register
+	MIIWDR = 0x8000;	// reset
+	mii_poll_busy();
+}
+
+/*  Function: cyg_bool mii_negotiate (void)
+ *
+ *  Description:
+ *     This routine is responsible for causing the external Ethernet
PHY
+ *     to begin the negotatiation process.
+ *
+ *  Parameters:
+ *     none
+ *
+ *  Return Value:
+ *     0: SUCCESS
+ *     1: ERROR
+ */
+
+cyg_bool mii_negotiate(void)
+{
+	int rev, timeout = 100000;
+
+	MIIAR = PHYS(4);
+
+	rev = *SysReg >> 24;
+	if(rev == 0)			// Full duplex 100Mbps must be
disabled on NCC chip Revision 0 and 1.
+		MIIWDR = 0x61;
+	else if(rev < 4)
+		MIIWDR = 0xe1;
+	else
+		MIIWDR = 0x1e1;
+
+	mii_poll_busy();
+
+	MIIAR = PHYS(0);
+	MIIWDR |= 0x1200;
+
+	mii_poll_busy();
+
+	while(timeout)
+	{
+		MIIAR = PHYS(1);
+		MIICR = 1;
+
+		mii_poll_busy();
+
+		if(0x24 == (MIIRDR & 0x24))
+			return 0;
+		else
+			timeout--;
+	}
+
+	return 1;
+}
+
+
+/*  Function: void mii_set_speed (cyg_bool speed, cyg_bool duplex)
+ *
+ *  Description:
+ *
+ *       This routine will set the speed and duplex of the external
PHY.
+ *
+ *  Parameters:
+ *      Speed
+ *        0: 10Mbit
+ *        1: 100Mbit
+ *      Duplex
+ *        0: Half
+ *        1: Full
+ *
+ *  Return Values:
+ *      none
+ */
+
+void mii_set_speed(cyg_bool speed, cyg_bool duplex)
+{
+	unsigned long int timeout = 1000000;
+
+	MIIAR = PHYS(0);	// select command register
+	MIIWDR = (speed << 13) | (duplex << 8);	// set speed and duplex
+	mii_poll_busy();
+
+
+	while(timeout)
+	{
+		MIIAR = PHYS(1);	// select status register
+		MIICR = 1;
+		mii_poll_busy();
+		if((MIIRDR) & 0x4)
+			break;
+		timeout--;
+	}
+}
+
+/*  Function: cyg_bool mii_check_speed
+ *
+ *  Description:
+ *
+ *       This routine will check the operating speed of the ethernet
+ *       interface.
+ *
+ *  Parameters:
+ *      none
+ *
+ *  Return Values:
+ *      0: 10Mbit Speed
+ *      1: 100Mbit Speed
+ */
+
+cyg_bool mii_check_speed(void)
+{
+	MIIAR = PHYS(17);
+	MIICR = 1;
+	mii_poll_busy();
+	return (MIIRDR >> 14) & 1;
+}
+
+/*  Function: void mii_check_duplex
+ *
+ *  Description:
+ *
+ *       This routine will check the operating duplex of the ethernet
+ *       interface.
+ *
+ *  Parameters:
+ *      none
+ *
+ *  Return Values:
+ *      0: Half Duplex
+ *      1: Full Duplex
+ */
+
+cyg_bool mii_check_duplex(void)
+{
+	MIIAR = PHYS(17);
+	MIICR = 1;
+	mii_poll_busy();
+	return (MIIRDR >> 9) & 1;
+}
diff -Naur
ecos/packages/devs/eth/arm/netarm/current/src/netarm_eth_drv.c
my_ecos/packages/devs/eth/arm/netarm/current/src/netarm_eth_drv.c
--- ecos/packages/devs/eth/arm/netarm/current/src/netarm_eth_drv.c
1970-01-01 01:00:00.000000000 +0100
+++ my_ecos/packages/devs/eth/arm/netarm/current/src/netarm_eth_drv.c
2004-11-27 16:10:49.062889600 +0100
@@ -0,0 +1,628 @@
+//=====================================================================
=====
+//
+//      netarm_eth_drv.c
+//
+//      NetSilion NET+ARM Ethernet Driver (DMA driven)
+//
+//=====================================================================
=====
+//=====================================================================
=====
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   	Harald Brandl (harald.brandl@fh-joanneum.at)
+// Contributors:  	Harald Brandl
+// Date:        	01.08.2004
+// Purpose:     	NET+ARM Ethernet Driver (DMA driven)
+// Description:
+//
+//####DESCRIPTIONEND####
+//
+//=====================================================================
=====
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/hal_arch.h>
+#include <cyg/infra/diag.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/eth/netdev.h>
+#include <cyg/io/eth/eth_drv.h>
+
+#include <pkgconf/devs_eth_arm_netarm.h>
+#include <cyg/hal/hal_platform_ints.h>
+#include <cyg/io/eth/eth_regs.h>
+#include <cyg/io/eth/MII.h>
+#include <cyg/io/eth/netarm_eth_drv.h>
+
+
+#define CYGNUM_HAL_INTERRUPT_DMA2		31
+#define CYGNUM_HAL_INTERRUPT_DMA1 		32
+
+
+#define BufferSizeA 128
+#define BufferSizeB 512
+#define BufferSizeC 1500
+
+#define NumA 10
+#define NumB 5
+#define NumC 10
+
+static cyg_mutex_t Key_Mutex;
+
+private_data_t driver_private = {NULL, 0, 0};
+
+unsigned char esa[6] = CYGDAT_DEVS_ETH_ARM_NETARM_ETH0_ESA;
+
+unsigned char RxBufferA[NumA][BufferSizeA];
+unsigned char RxBufferB[NumB][BufferSizeB];
+unsigned char RxBufferC[NumC][BufferSizeC];
+
+unsigned char TxBuffer[1500];
+unsigned char TxHeader[14];
+
+BDP_t RxBDP_A[NumA];
+BDP_t RxBDP_B[NumB];
+BDP_t RxBDP_C[NumC];
+
+BDP_t TxBDP[2];
+
+ETH_DRV_SC(netarm_sc,
+           (void *)&driver_private,	// driver specific data
+           "eth0",        			// Name for this
interface
+           netarm_start,
+           netarm_stop,
+           netarm_control,
+           netarm_can_send,
+           netarm_send,
+           netarm_recv,
+           netarm_deliver,
+           netarm_poll,
+           netarm_int_vector);
+
+
+NETDEVTAB_ENTRY(netarm_netdev,
+                "ETH_DRV",
+                netarm_init,
+                &netarm_sc);
+
+
+void fastcopy(void *buf, void *data, unsigned long len)
+{
+	asm volatile(
+
+		"STMDB SP!, {R11};"
+
+		"TST R1, #2;"			// test if aligned
+		"LDRNEH R3, [R1], #2;"
+		"STRNEH R3, [R0], #2;"
+		"SUBNE R2, R2, #2;"
+		"TST R1, #1;"
+		"LDRNEB R3, [R1], #1;"
+		"STRNEB R3, [R0], #1;"
+		"SUBNE R2, R2, #1;"
+
+		".START:"
+
+		"CMP R2, #44;"
+		"BLT .LASTBYTES;"
+		"LDMIA R1!, {R3 - R12, R14};"
+		"STMIA R0!, {R3 - R12, R14};"
+		"SUB R2, R2, #44;"
+
+		"CMP R2, #44;"
+		"BLT .LASTBYTES;"
+		"LDMIA R1!, {R3 - R12, R14};"
+		"STMIA R0!, {R3 - R12, R14};"
+		"SUB R2, R2, #44;"
+
+		"CMP R2, #44;"
+		"BLT .LASTBYTES;"
+		"LDMIA R1!, {R3 - R12, R14};"
+		"STMIA R0!, {R3 - R12, R14};"
+		"SUB R2, R2, #44;"
+
+		"CMP R2, #44;"
+		"BLT .LASTBYTES;"
+		"LDMIA R1!, {R3 - R12, R14};"
+		"STMIA R0!, {R3 - R12, R14};"
+		"SUB R2, R2, #44;"
+
+		"CMP R2, #44;"
+		"BLT .LASTBYTES;"
+		"LDMIA R1!, {R3 - R12, R14};"
+		"STMIA R0!, {R3 - R12, R14};"
+		"SUB R2, R2, #44;"
+
+		"CMP R2, #44;"
+		"BLT .LASTBYTES;"
+		"LDMIA R1!, {R3 - R12, R14};"
+		"STMIA R0!, {R3 - R12, R14};"
+		"SUB R2, R2, #44;"
+
+		"CMP R2, #44;"
+		"BLT .LASTBYTES;"
+		"LDMIA R1!, {R3 - R12, R14};"
+		"STMIA R0!, {R3 - R12, R14};"
+		"SUB R2, R2, #44;"
+
+		"CMP R2, #44;"
+		"BLT .LASTBYTES;"
+		"LDMIA R1!, {R3 - R12, R14};"
+		"STMIA R0!, {R3 - R12, R14};"
+		"SUB R2, R2, #44;"
+
+		"CMP R2, #44;"
+		"BLT .LASTBYTES;"
+		"LDMIA R1!, {R3 - R12, R14};"
+		"STMIA R0!, {R3 - R12, R14};"
+		"SUB R2, R2, #44;"
+
+		"CMP R2, #44;"
+		"BLT .LASTBYTES;"
+		"LDMIA R1!, {R3 - R12, R14};"
+		"STMIA R0!, {R3 - R12, R14};"
+		"SUB R2, R2, #44;"
+
+		"BGE .START;"
+
+
+		".LASTBYTES:"
+
+		"AND R14, R2, #0xfffffffc;"
+		"LDR PC, [PC, R14];"
+		"NOP;"
+
+		".SWITCH:"
+		".word	.CASE0;"
+		".word	.CASE1;"
+		".word	.CASE2;"
+		".word	.CASE3;"
+		".word	.CASE4;"
+		".word	.CASE5;"
+		".word	.CASE6;"
+		".word	.CASE7;"
+		".word	.CASE8;"
+		".word	.CASE9;"
+		".word	.CASE10;"
+
+		".CASE0:"
+		"B .END;"
+
+		".CASE1:"
+		"LDR R3, [R1]!;"
+		"STR R3, [R0]!;"
+		"B .END;"
+
+		".CASE2:"
+		"LDMIA R1!, {R3, R4};"
+		"STMIA R0!, {R3, R4};"
+		"B .END;"
+
+		".CASE3:"
+		"LDMIA R1!, {R3 - R5};"
+		"STMIA R0!, {R3 - R5};"
+		"B .END;"
+
+		".CASE4:"
+		"LDMIA R1!, {R3 - R6};"
+		"STMIA R0!, {R3 - R6};"
+		"B .END;"
+
+		".CASE5:"
+		"LDMIA R1!, {R3 - R7};"
+		"STMIA R0!, {R3 - R7};"
+		"B .END;"
+
+		".CASE6:"
+		"LDMIA R1!, {R3 - R8};"
+		"STMIA R0!, {R3 - R8};"
+		"B .END;"
+
+		".CASE7:"
+		"LDMIA R1!, {R3 - R9};"
+		"STMIA R0!, {R3 - R9};"
+		"B .END;"
+
+		".CASE8:"
+		"LDMIA R1!, {R3 - R10};"
+		"STMIA R0!, {R3 - R10};"
+		"B .END;"
+
+		".CASE9:"
+		"LDMIA R1!, {R3 - R11};"
+		"STMIA R0!, {R3 - R11};"
+		"B .END;"
+
+		".CASE10:"
+		"LDMIA R1!, {R3 - R12};"
+		"STMIA R0!, {R3 - R12};"
+
+		".END:"
+		"TST R2, #2;"
+		"LDRNEH R3, [R1], #2;"
+		"STRNEH R3, [R0], #2;"
+		"TST R2, #1;"
+		"LDRNEB R3, [R1], #1;"
+		"STRNEB R3, [R0], #1;"
+
+		"LDMIA SP!, {R11};"
+
+		:
+		: "r" (buf), "r" (data), "r" (len)
+		: "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
"r11", "r12", "r14"
+		);
+}
+
+bool KeyBufferFull(private_data_t *pd)
+{
+	int tmp = 0;
+
+	cyg_drv_mutex_lock(&Key_Mutex);
+
+	if((pd->key_head + 1) % MaxKeys == pd->key_tail)
+	{
+		tmp = 1;
+	}
+
+	cyg_drv_mutex_unlock(&Key_Mutex);
+
+	return tmp;
+}
+
+
+void AddKey(unsigned long key, private_data_t *pd)
+{
+
+	cyg_drv_mutex_lock(&Key_Mutex);
+
+	pd->KeyBuffer[pd->key_head] = key;
+	pd->key_head = (pd->key_head + 1) % MaxKeys;
+
+	cyg_drv_mutex_unlock(&Key_Mutex);
+}
+
+unsigned long GetKey(private_data_t *pd)
+{
+	unsigned long key = 0;
+
+	cyg_drv_mutex_lock(&Key_Mutex);
+
+	if(pd->key_tail != pd->key_head)
+	{
+		key = pd->KeyBuffer[pd->key_tail];
+		pd->key_tail = (pd->key_tail + 1) % MaxKeys;
+	}
+
+	cyg_drv_mutex_unlock(&Key_Mutex);
+
+	return key;
+}
+
+
+static cyg_uint32 dma_rx_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+
+	// block this interrupt until the dsr completes
+	cyg_drv_interrupt_mask(vector);
+
+	// tell ecos to allow further interrupt processing
+	cyg_drv_interrupt_acknowledge(vector);
+
+	return CYG_ISR_CALL_DSR;	// call the dsr
+}
+
+static void dma_rx_dsr(cyg_vector_t vector, cyg_ucount32 count,
cyg_addrword_t data)
+{
+
+	eth_drv_dsr( vector, count, data );
+
+	DMA1A_SR |= 0x80000000;		// acknowledge normal completion
interrupt
+	DMA1B_SR |= 0x80000000;
+	DMA1C_SR |= 0x80000000;
+
+	cyg_drv_interrupt_unmask(vector);
+}
+
+static cyg_uint32 dma_tx_isr(cyg_vector_t vector, cyg_addrword_t data)
+{
+
+	// block this interrupt until the dsr completes
+	cyg_drv_interrupt_mask(vector);
+
+	// tell ecos to allow further interrupt processing
+	cyg_drv_interrupt_acknowledge(vector);
+
+	return CYG_ISR_CALL_DSR;	// invoke the dsr
+}
+
+static void dma_tx_dsr(cyg_vector_t vector, cyg_ucount32 count,
cyg_addrword_t data)
+{
+
+	eth_drv_dsr( vector, count, data );
+
+	DMA2_SR |= 0x80000000; // acknowledge interrupt
+
+	cyg_drv_interrupt_unmask(vector);
+}
+
+static void SetupDMA(void)
+{
+	int i;
+
+	for(i = 0; i < NumA; i++)
+	{
+		RxBDP_A[i].BufferPointer = ((unsigned long)RxBufferA[i])
& 0x3fffffff;
+		RxBDP_A[i].BufferLen = BufferSizeA;
+	}
+
+	RxBDP_A[i - 1].W = 1;
+
+	for(i = 0; i < NumB; i++)
+	{
+		RxBDP_B[i].BufferPointer = ((unsigned long)RxBufferB[i])
& 0x3fffffff;
+		RxBDP_B[i].BufferLen = BufferSizeB;
+	}
+
+	RxBDP_B[i - 1].W = 1;
+
+	for(i = 0; i < NumC; i++)
+	{
+		RxBDP_C[i].BufferPointer = ((unsigned long)RxBufferC[i])
& 0x3fffffff;
+		RxBDP_C[i].BufferLen = BufferSizeC;
+	}
+
+	RxBDP_C[i - 1].W = 1;
+
+	DMA1A_BDP = (unsigned long)RxBDP_A;
+	DMA1A_CR = 0x82000000;	//burst transfer
+	DMA1A_SR |= 0xa00000;
+
+	DMA1B_BDP = (unsigned long)RxBDP_B;
+	DMA1B_CR = 0x82000000;	//burst transfer
+	DMA1B_SR |= 0xa00000;
+
+	DMA1C_BDP = (unsigned long)RxBDP_C;
+	DMA1C_CR = 0x82000000;	//burst transfer
+	DMA1C_SR |= 0xa00000;
+
+
+	// setup dma transmitter
+
+	TxBDP[0].BufferPointer = ((unsigned long)TxHeader) & 0x3fffffff;
+	TxBDP[1].BufferPointer = ((unsigned long)TxBuffer) & 0x3fffffff;
+	TxBDP[1].L = 1;
+	TxBDP[1].W = 1;
+
+	DMA2_BDP = (unsigned long)TxBDP;
+	DMA2_CR = 0x86000000;	//burst transfer
+	DMA2_SR |= 0x800000;
+
+}
+
+
+static bool netarm_init(struct cyg_netdevtab_entry *tab)
+{
+	struct eth_drv_sc *sc = (struct eth_drv_sc
*)tab->device_instance;
+	cyg_bool duplex;
+	static cyg_interrupt dma_rx_int_object, dma_tx_int_object;
+	static cyg_handle_t dma_rx_int_handle, dma_tx_int_handle;
+
+	// setup dma receiver
+	SetupDMA();
+
+	mii_reset();
+	mii_negotiate();				// initialize
PHY
+	duplex = mii_check_duplex();
+
+	// Ethernet Controller Initializatition
+
+	MACCR 				= (0x1c | (duplex << 1));
// auto CRC, late collision retry
+	STLCR 				= 0x3;
// insert MAC source address into ethernet frame
+	BtBIPGGapTimerR 	= 0x14;
// standard values
+	NonBtBIPGGapTimerR  = ((0x9 << 7) | 0x11);
// standard values
+	CollWinR 			= ((0x37 << 8) | 0xf);
// standard values
+	SAFR 				= 0x1;
// broadcast mode
+	EthGenCR 			= (0x40400400 | (duplex <<
16));// dma mode, full duplex, enable pNA mode(needed for alignment)
+
+	cyg_drv_interrupt_create(
+		CYGNUM_HAL_INTERRUPT_DMA1,		// Interrupt
Vector
+		0,
// Interrupt Priority
+		(cyg_addrword_t)&netarm_sc,		// Reference to
Driver Instance
+		dma_rx_isr,
+		dma_rx_dsr,
+		&dma_rx_int_handle,
+		&dma_rx_int_object);
+
+	cyg_drv_interrupt_create(
+		CYGNUM_HAL_INTERRUPT_DMA2,		// Interrupt
Vector
+		0,
// Interrupt Priority
+		(cyg_addrword_t)&netarm_sc,		// Reference to
Driver Instance
+		dma_tx_isr,
+		dma_tx_dsr,
+		&dma_tx_int_handle,
+		&dma_tx_int_object);
+
+	cyg_drv_interrupt_attach(dma_rx_int_handle);
+
+	cyg_drv_interrupt_attach(dma_tx_int_handle);
+
+	cyg_mutex_init(&Key_Mutex);
+
+	sc->funs->eth_drv->init(sc, esa);
+
+	return true;
+}
+
+
+static void netarm_recv(struct eth_drv_sc *sc, struct eth_drv_sg
*sg_list, int sg_len)
+{
+    int i, len;
+    private_data_t *pd = (private_data_t *)(sc->driver_private);
+    unsigned char *data, *buf = pd->RxBuffer;
+
+    for (i = 0;  i < sg_len;  i++) {
+        data = (unsigned char *)(sg_list[i].buf);
+        len = sg_list[i].len;
+        if (len)
+        {
+			if(i == 1)
+			{
+				buf += 2;
+			}
+
+            fastcopy(data, buf, len);
+            buf += len;
+        }
+    }
+}
+
+
+static void netarm_deliver(struct eth_drv_sc *sc)
+{
+	static int a = 0, b = 0, c = 0;
+	unsigned long key;
+	private_data_t *pd = (private_data_t *)(sc->driver_private);
+
+	while((key = GetKey(pd)))
+	{
+		sc->funs->eth_drv->tx_done(sc, key, 0);
+	}
+
+	while(RxBDP_A[a].F)
+	{
+		pd->RxBuffer = (unsigned char
*)RxBDP_A[a].BufferPointer;
+		sc->funs->eth_drv->recv(sc, RxBDP_A[a].BufferLen);
+		RxBDP_A[a].BufferLen = BufferSizeA;
+		RxBDP_A[a].F = 0;
+		a = (a + 1) % NumA;
+	}
+
+	while(RxBDP_B[b].F)
+	{
+		pd->RxBuffer = (unsigned char
*)RxBDP_B[b].BufferPointer;
+		sc->funs->eth_drv->recv(sc, RxBDP_B[b].BufferLen);
+		RxBDP_B[b].BufferLen = BufferSizeB;
+		RxBDP_B[b].F = 0;
+		b = (b + 1) % NumB;
+	}
+
+	while(RxBDP_C[c].F)
+	{
+		pd->RxBuffer = (unsigned char
*)RxBDP_C[c].BufferPointer;
+		sc->funs->eth_drv->recv(sc, RxBDP_C[c].BufferLen);
+		RxBDP_C[c].BufferLen = BufferSizeC;
+		RxBDP_C[c].F = 0;
+		c = (c + 1) % NumC;
+	}
+
+	cyg_drv_dsr_lock();
+		DMA1A_SR |= 0x20000000;
+		DMA1B_SR |= 0x20000000;
+		DMA1C_SR |= 0x20000000;
+	cyg_drv_dsr_unlock();
+}
+
+
+static int netarm_can_send(struct eth_drv_sc *sc)
+{
+	private_data_t *pd = (private_data_t *)(sc->driver_private);
+
+	if(TxBDP[0].F || TxBDP[1].F || KeyBufferFull(pd))
+	{
+		return 0;
+	}
+
+	return 1;
+}
+
+static void netarm_send(
+	struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
int total_len, unsigned long key)
+{
+	private_data_t *pd = (private_data_t *)(sc->driver_private);
+    register int i, len;
+    register unsigned char *data, *buf = TxBuffer;
+
+	AddKey(key, pd);
+
+    // Put data into buffer
+    for (i = 0;  i < sg_len;  i++) {
+        data = (unsigned char *)sg_list[i].buf;
+        len = sg_list[i].len;
+
+		if(i == 0)
+		{
+			if((unsigned long)data & 0x3)
+			{
+				memcpy(TxHeader, data, 0xe);
+			}
+			else
+			{
+				fastcopy(TxHeader, data, 0xe);
+			}
+
+			len -= 0xe;
+			data += 0xe;
+		}
+
+        if (len)
+        {
+			fastcopy(buf, data, len);
+			buf += len;
+		}
+    }
+
+	TxBDP[0].BufferLen = 0xe;
+	TxBDP[0].F = 1;
+	TxBDP[1].BufferLen = total_len - 0xe;
+	TxBDP[1].F = 1;
+
+	cyg_drv_dsr_lock();
+		DMA2_SR |= 0xf0000000;
+	cyg_drv_dsr_unlock();
+}
+
+
+static void netarm_start(struct eth_drv_sc *sc, unsigned char *enaddr,
int flags)
+{
+	SetMAC(enaddr);			// set MAC address
+	EthGenCR |= 0x80800000;	// enable Rx und Tx FIFO
+	cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_DMA1);
+	cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_DMA2);
+}
+
+static void netarm_stop(struct eth_drv_sc *sc)
+{
+	EthGenCR &= 0x7f7fffff;
+	cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_DMA1);
+	cyg_drv_interrupt_mask(CYGNUM_HAL_INTERRUPT_DMA2);
+}
+
+static int netarm_control(struct eth_drv_sc *sc, unsigned long key,
void *data, int len)
+{
+    switch (key)
+    {
+    	case ETH_DRV_SET_MAC_ADDRESS:
+        	return 0;
+        	break;
+    	case ETH_DRV_SET_MC_LIST:
+    	case ETH_DRV_SET_MC_ALL:
+        	return 0;
+    	default:
+        	return 1;
+        	break;
+    }
+}
+
+static void netarm_poll(struct eth_drv_sc *sc)
+{
+}
+
+static int netarm_int_vector(struct eth_drv_sc *sc)
+{
+	return CYGNUM_HAL_INTERRUPT_DMA1;
+}
+
+static void SetMAC(unsigned char *MAC)
+{
+	strcpy(esa, MAC);
+	SAR1 = (esa[1] << 8) | esa[0];	// set MAC address
+	SAR2 = (esa[3] << 8) | esa[2];
+	SAR3 = (esa[5] << 8) | esa[4];
+}
diff -Naur ecos/packages/ecos.db my_ecos/packages/ecos.db
--- ecos/packages/ecos.db	2004-11-30 13:31:59.917055700 +0100
+++ my_ecos/packages/ecos.db	2004-11-30 11:08:40.112772800 +0100
@@ -2333,6 +2333,16 @@
 		The NetARM HAL package provides the support needed to
run
 		eCos on an NetSilicon NetARM evaluation board."
 }
+
+package CYGPKG_DEVS_ETH_ARM_NETARM {
+	alias 		{ "ARM NET+50 ethernet driver"
+			   devs_eth_arm_netarm netarm_eth_driver }
+	hardware
+	directory	devs/eth/arm/netarm
+	script		netarm_eth_driver.cdl
+        description     "Ethernet driver for NET+50 ethernet
interfaces."
+}
+
 #
------------------------------------------------------------------------
--
 # ARM packages
 package CYGPKG_HAL_ARM {
@@ -3793,8 +3803,10 @@
 target netarm {
 	alias 		{ "NetSilicon NetARM board" netarm }
 	packages	{ CYGPKG_HAL_ARM
-				  CYGPKG_HAL_ARM_NETARM
-		  		}
+			  CYGPKG_HAL_ARM_NETARM
+			  CYGPKG_IO_SERIAL_ARM_NETARM
+			  CYGPKG_DEVS_ETH_ARM_NETARM
+	}
 	description "
 	The netarm target provides the packages needed to run eCos on a
NetSilicon
 	NET+ARM evaluation board."


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]