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]

Atlas ethernet update


Index: ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/mips/atlas/current/ChangeLog,v
retrieving revision 1.7
diff -u -5 -r1.7 ChangeLog
--- ChangeLog	13 Mar 2003 18:49:37 -0000	1.7
+++ ChangeLog	21 Mar 2003 18:15:47 -0000
@@ -1,5 +1,11 @@
+2003-03-21  Nick Garnett  <nickg at balti dot calivar dot com>
+
+	* src/saa9730.h: 
+	* src/if_atlas.c:
+	Many small changes to make this driver work correctly in eCos.
+
 2003-03-13  Nick Garnett  <nickg at balti dot calivar dot com>
 
 	* cdl/atlas_eth_drivers.cdl:
 	Changed CYGPKG_DEVS_ETH_ARM_ATLAS_OPTIONS to
 	CYGPKG_DEVS_ETH_MIPS_ATLAS_OPTIONS. 
Index: src/if_atlas.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/mips/atlas/current/src/if_atlas.c,v
retrieving revision 1.7
diff -u -5 -r1.7 if_atlas.c
--- src/if_atlas.c	13 Mar 2003 18:49:37 -0000	1.7
+++ src/if_atlas.c	21 Mar 2003 18:15:48 -0000
@@ -7,10 +7,11 @@
 //==========================================================================
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg at calivar dot com>
 //
 // 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.
 //
@@ -31,12 +32,12 @@
 // 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/
+// Alternative licenses for eCos may be arranged by contacting the copyright
+// holders.
 // -------------------------------------------
 //####ECOSGPLCOPYRIGHTEND####
 //####BSDCOPYRIGHTBEGIN####
 //
 // -------------------------------------------
@@ -49,11 +50,11 @@
 //####BSDCOPYRIGHTEND####
 //==========================================================================
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    msalter
-// Contributors: msalter
+// Contributors: msalter, nickg
 // Date:         2000-12-06
 // Purpose:      
 // Description:  hardware driver for SAA9730 ethernet
 //              
 //
@@ -75,10 +76,11 @@
 #include <cyg/infra/cyg_type.h>
 #include <cyg/hal/hal_arch.h>
 #include <cyg/hal/hal_endian.h>
 #include <cyg/hal/hal_intr.h>
 #include <cyg/hal/hal_cache.h>
+#include <cyg/hal/hal_if.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>
 
@@ -110,10 +112,13 @@
 #include "saa9730.h"
 
 // Exported statistics and the like
 #include <cyg/io/eth/eth_drv_stats.h>
 
+#ifndef CYGPKG_REDBOOT
+//#define DEBUG
+#endif
 #define db_printf diag_printf
 
 #define ETHER_ADDR_LEN 6
 
 static unsigned poll_count = 0;  // for bug workaround
@@ -165,35 +170,46 @@
 NETDEVTAB_ENTRY(atlas_netdev, 
                 "atlas", 
                 atlas_saa9730_init, 
                 &atlas_sc);
 
-#ifdef CYGSEM_ARM_ATLAS_SET_ESA
-static unsigned char enaddr[] = CYGDAT_ARM_ATLAS_ESA;
+#ifdef CYGSEM_MIPS_ATLAS_SET_ESA
+static unsigned char enaddr[] = CYGDAT_MIPS_ATLAS_ESA;
 #else
 static unsigned char enaddr[ETHER_ADDR_LEN];
 #endif
 
 static void saa9730_poll(struct eth_drv_sc *sc);
 
 // This ISR is called when the ethernet interrupt occurs
 static int
 saa9730_isr(cyg_vector_t vector, cyg_addrword_t data)
 {
+    struct saa9730_priv_data *spd = (struct saa9730_priv_data *)data;
+    unsigned long __base = spd->base;    
+
 #ifndef CYGPKG_REDBOOT    
+    SAA9730_EVM_IER_SW &= ~(SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
+    SAA9730_EVM_ISR = SAA9730_EVM_LAN_INT;
     cyg_drv_interrupt_mask(vector);
-#endif    
+#endif
+#ifdef DEBUG
+    db_printf("saa9730_isr\n");
+#endif
     return (CYG_ISR_HANDLED|CYG_ISR_CALL_DSR);  // Run the DSR
 }
 
 #ifndef CYGPKG_REDBOOT
 static 
 void saa9730_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
 {
     struct saa9730_priv_data *spd = (struct saa9730_priv_data *)data;
     struct cyg_netdevtab_entry *ndp = (struct cyg_netdevtab_entry *)(spd->ndp);
     struct eth_drv_sc *sc = (struct eth_drv_sc *)(ndp->device_instance);
+#ifdef DEBUG
+    db_printf("saa9730_dsr\n");    
+#endif
 
     eth_drv_dsr(vector, count, (cyg_addrword_t)sc);
 }
 #endif
 
@@ -249,10 +265,11 @@
 
     if (buf_nr)
         SAA9730_OK2USE |= SAA9730_OK2USE_RXB;
     else
         SAA9730_OK2USE |= SAA9730_OK2USE_RXA;
+
 }
 
 static void
 __init_cam(struct saa9730_priv_data *spd)
 {
@@ -313,22 +330,25 @@
     SAA9730_PKTCNT = ((SAA9730_TXPKTS_PER_BUFFER << 24) |
 		      (SAA9730_TXPKTS_PER_BUFFER << 16) |
 		      (SAA9730_RXPKTS_PER_BUFFER <<  8) |
 		      (SAA9730_RXPKTS_PER_BUFFER <<  0));
 
-    SAA9730_OK2USE = SAA9730_OK2USE_RXA | SAA9730_OK2USE_RXB;
+    SAA9730_OK2USE = 0;
 
     __select_buffer(spd, 0);
 
     // initialize DMA control register
     SAA9730_DMACTL = SAA9730_DMACTL_BLKINT |
 	             SAA9730_DMACTL_MAXXFER_ANY |
 	             SAA9730_DMACTL_ENDIAN_LITTLE;
-#ifdef CYGPKG_REDBOOT
+
     SAA9730_DMACTL |= SAA9730_DMACTL_RXINT;
     SAA9730_DMACTL |= (1<<SAA9730_DMACTL_RXINTCNT_SHIFT);
     SAA9730_DMACTL &= ~SAA9730_DMACTL_BLKINT;
+
+#ifndef CYGPKG_REDBOOT
+    SAA9730_DMACTL |= SAA9730_DMACTL_TXINT;
 #endif
     
     SAA9730_TIMOUT = 200;
 
     // accept broadcast packets */
@@ -337,18 +357,23 @@
 
     SAA9730_TXCTL = 0;
     SAA9730_RXCTL |= SAA9730_RXCTL_STRIPCRC;
 
     SAA9730_CAMENA = 1;
+
 }
 
 static void
 __check_mii(struct saa9730_priv_data *spd)
 {
     unsigned long __base = spd->base;
     cyg_uint32 opmode;
 
+#ifdef DEBUG
+    db_printf("__check_mii\n");    
+#endif
+    
     // spin till station is not busy
     while (SAA9730_MDCTL & SAA9730_MDCTL_BUSY)
 	;
 
     // set PHY address = 'STATUS'
@@ -376,22 +401,22 @@
 	hal_delay_us(1000);
 
         opmode = (SAA9730_MDDATA & PHY_REG31_OPMODE_MSK) >> PHY_REG31_OPMODE_SHIFT;
 
 #ifdef DEBUG
-	diag_printf("MII mode %d\n", opmode);
+	db_printf("MII mode %d\n", opmode);
 #endif
 
 	if ((opmode == OPMODE_10BASET_FULLDUPLEX) ||
 	    (opmode == OPMODE_100BASEX_FULLDUPLEX))
             SAA9730_MACCTL = SAA9730_MACCTL_CONMODE_FORCE_MII | SAA9730_MACCTL_FULLDUP;
         else
             SAA9730_MACCTL = SAA9730_MACCTL_CONMODE_FORCE_MII;
     }
 #ifdef DEBUG
     else
-	diag_printf("Link is down\n");
+	db_printf("Link is down\n");
 #endif
 }
 
 
 static void
@@ -428,11 +453,11 @@
     static int initialized = 0; // only probe PCI et al *once*
     struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
     struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
 
 #ifdef DEBUG
-    diag_printf("atlas_saa9730_init\n");
+    db_printf("atlas_saa9730_init\n");
 #endif
 
     if (0 == initialized) {
 	cyg_pci_device_id devid;
 	cyg_pci_device dev_info;
@@ -479,10 +504,12 @@
 		      CYG_PCI_DEV_GET_BUS(devid),
 		      CYG_PCI_DEV_GET_DEV(CYG_PCI_DEV_GET_DEVFN(devid)),
 		      spd->base, spd->vector);
 #endif
 
+            spd->ndp = tab;
+            
 #ifndef CYGPKG_REDBOOT
 	    cyg_drv_interrupt_create(
 		    spd->vector,
                     0,                  // Priority - unused
                     (CYG_ADDRWORD)spd,  // Data item passed to ISR & DSR
@@ -492,21 +519,20 @@
                     &spd->interrupt_object ); // space for int obj
 
 	    cyg_drv_interrupt_attach(spd->interrupt_handle);
 	    cyg_drv_interrupt_acknowledge(spd->vector);
 	    cyg_drv_interrupt_unmask(spd->vector);
-#else
+#endif
             {
                 // When in Redboot we want to get RX interrupts. These
                 // will be picked up by the default interrupt handler and
                 // checked for ^C.
                 unsigned long __base = spd->base;
                 SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);                
                 SAA9730_EVM_IER |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
                 SAA9730_EVM_ISR |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
             }
-#endif
 
 #ifdef DEBUG
 	    db_printf(" **** Device enabled for I/O and Memory and Bus Master\n");
 #endif
 
@@ -514,27 +540,29 @@
 #ifdef DEBUG
             db_printf("eth0 not found\n");
 #endif
         }
 
+        saa9730_stop(sc);
+        
 	spd->active = 0;
 
 	initialized = 1;
     }
 
     // Fetch hardware address
 #if defined(CYGPKG_REDBOOT) && \
     defined(CYGSEM_REDBOOT_FLASH_CONFIG) && \
-    !defined(CYGSEM_ARM_ATLAS_SET_ESA)
+    !defined(CYGSEM_MIPS_ATLAS_SET_ESA)
     flash_get_config("atlas_esa", enaddr, CONFIG_ESA);
 #else
-#if 0
-    for (i = 0;  i < ETHER_ADDR_LEN;  i += 2) {
-        unsigned short esa_reg = get_reg(PP_IA+i);
-        enaddr[i] = esa_reg & 0xFF;
-        enaddr[i+1] = esa_reg >> 8;
-    }
+#define CONFIG_ESA     6
+    CYGACC_CALL_IF_FLASH_CFG_OP( CYGNUM_CALL_IF_FLASH_CFG_GET,
+                                 "atlas_esa", enaddr, CONFIG_ESA );
+#ifdef DEBUG
+    db_printf("ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+              enaddr[0],enaddr[1],enaddr[2],enaddr[3],enaddr[4],enaddr[5]);
 #endif
 #endif
 
     saa9730_reset(spd);
 
@@ -581,10 +609,12 @@
     SAA9730_DMACTL |= SAA9730_DMACTL_ENTX;
 
     // for rx, turn on DMA first
     SAA9730_DMACTL |= SAA9730_DMACTL_ENRX;
     SAA9730_RXCTL |= SAA9730_RXCTL_ENRX;
+
+    __select_buffer(spd, spd->next_rx_bindex);    
 }
 
 //
 // This function is called to "start up" the interface.  It may be called
 // multiple times, even when the hardware is already running.  It will be
@@ -736,21 +766,25 @@
     unsigned long __base = spd->base;
     cyg_uint32  status, flag, size;
     cyg_uint32  *pkt;
     int         i, j;
 
-#ifdef CYGPKG_REDBOOT    
+#ifdef DEBUG
+    db_printf("__check_rxstate\n");        
+#endif
+
+#ifdef CYGPKG_REDBOOT
     // Clear SAA9730 LAN interrupt and re-enable interrupts.
     SAA9730_EVM_ISR = SAA9730_EVM_LAN_INT;
     SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
 #endif
     
     if ((SAA9730_DBGRXS & SAA9730_DBGRXS_RXDII_MASK) == SAA9730_DBGRXS_RXDII_ERROR) {
         // re-init driver and controller
 #ifdef DEBUG
         db_printf("DBGRXS: reset\n");
-#endif        
+#endif
 	saa9730_reset(spd);
 	__do_start(spd);
 	return;
     }
 
@@ -763,11 +797,11 @@
             flag   = status & RXPACKET_STATUS_FLAG_MASK;
             if (flag == RX_INVALID_STAT || size > 1514 || *(pkt - 1)) {
 		// re-init driver and controller
 #ifdef DEBUG
                 db_printf("rxpkt: reset\n");
-#endif                
+#endif
 		saa9730_reset(spd);
 		__do_start(spd);
 		return;
             }
         }
@@ -857,10 +891,13 @@
     struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
     int	                 bindex, pindex, done;
     volatile cyg_uint32 *pkt;
     cyg_uint32           status, pktlen; 
 
+#ifdef DEBUG
+    db_printf("__rx_poll\n");
+#endif
     if (!spd->active)
 	return;
 
     done = 0;
     while (!done) {
@@ -873,11 +910,13 @@
         pkt = spd->rx_buffer[bindex][pindex];
 
 	// stop now if no more packets
         if (((status = CYG_LE32_TO_CPU(*pkt)) & RXPACKET_STATUS_FLAG_MASK) == RX_READY)
             break;
-
+#ifdef DEBUG
+        db_printf("__rx_poll pkt %08x status %08x\n",pkt,status);
+#endif
 	// if this is the first packet in a buffer, switch the SAA9730 to
 	// use the next buffer for subsequent incoming packets.
 	if (pindex == 0)
 	    __select_buffer(spd, bindex == 0);
             
@@ -889,11 +928,15 @@
 	    if (pktlen > 0) {
 		(sc->funs->eth_drv->recv)(sc, pktlen);
 		// done = 1;
 	    }
 	}
-
+#ifdef DEBUG
+        else
+            db_printf("rx bad: %08x %08x\n",pkt,status);
+#endif
+        
 	/* go to next packet in sequence */
 	spd->next_rx_pindex++;
 	if (spd->next_rx_pindex >= SAA9730_RXPKTS_PER_BUFFER) {
 	    spd->next_rx_pindex = 0;
 	    spd->next_rx_bindex++;
@@ -974,11 +1017,11 @@
     struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
 
 #ifndef CYGPKG_REDBOOT
     cyg_drv_interrupt_mask(spd->vector);
 #endif
-    
+
     (void)saa9730_isr(spd->vector, (cyg_addrword_t)spd);
 
     __do_deliver(sc);
 
     cyg_drv_interrupt_acknowledge(spd->vector);
@@ -992,11 +1035,20 @@
 // The deliver function (ex-DSR)  handles the ethernet [logical] processing
 static void
 saa9730_deliver(struct eth_drv_sc *sc)
 {
     struct saa9730_priv_data *spd = (struct saa9730_priv_data *)sc->driver_private;
+    unsigned long __base = spd->base;    
 
     if (spd->active)
 	__do_deliver(sc);
+
+    cyg_drv_interrupt_acknowledge(spd->vector);
+
+#ifndef CYGPKG_REDBOOT
+    // Clear SAA9730 LAN interrupt and re-enable interrupts.
+    SAA9730_EVM_IER_SW |= (SAA9730_EVM_LAN_INT|SAA9730_EVM_MASTER);
+    cyg_drv_interrupt_unmask(spd->vector);
+#endif    
 }
 
 
Index: src/saa9730.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/mips/atlas/current/src/saa9730.h,v
retrieving revision 1.4
diff -u -5 -r1.4 saa9730.h
--- src/saa9730.h	23 May 2002 23:00:44 -0000	1.4
+++ src/saa9730.h	21 Mar 2003 18:15:48 -0000
@@ -9,10 +9,11 @@
 //==========================================================================
 //####ECOSGPLCOPYRIGHTBEGIN####
 // -------------------------------------------
 // This file is part of eCos, the Embedded Configurable Operating System.
 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
+// Copyright (C) 2003 Nick Garnett <nickg at calivar dot com>
 //
 // 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.
 //
@@ -33,19 +34,19 @@
 // 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/
+// Alternative licenses for eCos may be arranged by contacting the copyright
+// holders.
 // -------------------------------------------
 //####ECOSGPLCOPYRIGHTEND####
 //==========================================================================
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):     msalter
-// Contributors:  msalter
+// Contributors:  msalter, nickg
 // Date:          2000-12-09
 // Description:   Definitions for Philips SAA9730 Ethernet module.
 //
 //####DESCRIPTIONEND####
 */
@@ -306,10 +307,14 @@
 #  define SAA9730_DBGRXS_RXPI_MASK           (0x3ff << 16)
 #  define SAA9730_DBGRXS_RXPI_ERROR          (0x001 << 16)
 #  define SAA9730_DBGRXS_RXDII_MASK          0x1ff
 #  define SAA9730_DBGRXS_RXDII_ERROR         8
 
+
+#define SAA9730_DBGRXFIFO       *((volatile unsigned *)(__base + 0x20510)) // DEBUG
+
+#define SAA9730_DBGLANSTA       *((volatile unsigned *)(__base + 0x20514)) // DEBUG
 
 // ******** Packet control/status **********
 
 #define TXPACKET_CTL_FLAG_MASK      (0x3 << 30)
 #  define TX_EMPTY                  (0 << 30)


-- 
Nick Garnett                    eCos Kernel Architect
http://www.ecoscentric.com/     The eCos and RedBoot experts


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