This is the mail archive of the ecos-patches@sourceware.org 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]

NS DP83816 patches


This is the first of a number of patches being submitted by eCosCentric from our internal tree to the public tree. This is to try and bring our sources and anoncvs into line with some of the (many) improvements we've made in our tree. However it won't be all our changes by any means, not yet :).

In this patch for the NS DP83816 eth driver, some of our changes, and anoncvs changes overlap, and I've retained the anoncvs implementation for backward compatibility but deprecated.

Checked in.

Jifl
--
eCosCentric    http://www.eCosCentric.com/    The eCos and RedBoot experts
------["The best things in life aren't things."]------      Opinions==mine
Index: ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/ns/dp83816/current/ChangeLog,v
retrieving revision 1.5
diff -u -5 -p -r1.5 ChangeLog
--- ChangeLog	21 Jul 2005 18:10:55 -0000	1.5
+++ ChangeLog	20 Jul 2006 15:48:49 -0000
@@ -11,10 +11,27 @@
 2004-08-24  Gary Thomas  <gary@mlbassoc.com>
 
 	* src/if_dp83816.c: Enable start/stop functions (device was always
 	enabled once configured before)
 
+2004-05-14  Nick Garnett  <nickg@ecoscentric.com>
+
+	* src/if_dp83816.c (dp83816_init): Make ESA diag_printf()
+	controlled by DEBUG flag.
+	(dp83816_init): 
+	(dp83816_poll): Fixed interrupt enable, masking and acknowledges
+	so that the driver correctly handles Ctrl-C interrupts in RedBoot.
+
+2004-05-13  Nick Garnett  <nickg@ecoscentric.com>
+
+	* src/if_dp83816.c (dp83816_poll): Removed test for locked up
+	transmit engine. This test triggers in otherwise normal situations
+	and the warm reset messes things up a lot in both the driver and
+	network stack.
+	(dp83816_recv): Avoid memcpy() when passed a NULL buffer, this can
+	happen when the stack runs out of MBUFs.
+
 2003-10-14  Gary Thomas  <gary@mlbassoc.com>
 
 	* src/if_dp83816.c (dp83816_poll): Try to better detect condition
 	where device just stops.  This seems to be related to Rx overruns,
 	but there is no status reported.  The best that can be done is
@@ -35,10 +52,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) 2004 eCosCentric Limited
 //
 // 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.
 //
Index: src/dp83816.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/ns/dp83816/current/src/dp83816.h,v
retrieving revision 1.3
diff -u -5 -p -r1.3 dp83816.h
--- src/dp83816.h	21 Jul 2005 18:10:56 -0000	1.3
+++ src/dp83816.h	20 Jul 2006 15:48:50 -0000
@@ -8,10 +8,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 Gary Thomas
+// Copyright (C) 2004 eCosCentric Limited
 //
 // 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.
 //
@@ -61,27 +62,27 @@
 // 0 disables all debug output
 // 1 for process debug output
 // 2 for added data IO output: get_reg, put_reg
 // 4 for packet allocation/free output
 // 8 for only startup status, so we can tell we're installed OK
-#define DEBUG 0x0
-
+#define DEBUG 0
+__externC int norecurse;
 #if DEBUG & 1
-#define DEBUG_FUNCTION() do { diag_printf("%s\n", __FUNCTION__); } while (0)
+#define DEBUG_FUNCTION() do { if (!norecurse) { norecurse=1; diag_printf("%s\n", __FUNCTION__); norecurse=0;}} while (0)
 #define DEBUG_LINE() do { diag_printf("%d\n", __LINE__); } while (0)
 #else
 #define DEBUG_FUNCTION() do {} while(0)
 #define DEBUG_LINE() do {} while(0)
 #endif
 
 // ------------------------------------------------------------------------
 // Buffer descriptors
 typedef struct dp83816_bd {
-    struct dp83816_bd *next;  // Next descriptor
-    unsigned long      stat;  // Buffer status & flags
-    unsigned char     *buf;   // Buffer memory
-    unsigned long      key;   // Internal use only
+    volatile struct dp83816_bd *next;  // Next descriptor
+    volatile unsigned long      stat;  // Buffer status & flags
+    volatile unsigned char     *buf;   // Buffer memory
+    volatile unsigned long      key;   // Internal use only
 } dp83816_bd_t;
 
 // ------------------------------------------------------------------------
 // Private driver structure
 typedef struct dp83816_priv_data {
Index: src/if_dp83816.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/ns/dp83816/current/src/if_dp83816.c,v
retrieving revision 1.7
diff -u -5 -p -r1.7 if_dp83816.c
--- src/if_dp83816.c	21 Jul 2005 18:10:56 -0000	1.7
+++ src/if_dp83816.c	20 Jul 2006 15:48:50 -0000
@@ -8,10 +8,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, 2004 Gary Thomas
+// Copyright (C) 2004 eCosCentric Limited
 //
 // 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.
 //
@@ -60,14 +61,19 @@
 #include <cyg/infra/diag.h>
 #include <cyg/hal/drv_api.h>
 #include <cyg/hal/hal_if.h>
 #include <cyg/io/eth/eth_drv.h>
 #include <cyg/io/eth/netdev.h>
+#include <string.h> // memcpy
 
 #include "dp83816.h"
 #include CYGDAT_DEVS_ETH_NS_DP83816_INL
 
+#if DEBUG & 1
+int norecurse;
+#endif
+
 #ifdef CYGHWR_NS_DP83816_USE_EEPROM
 static cyg_uint16 dp83816_eeprom_read(struct dp83816_priv_data *dp, int location);
 #endif
 
 #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
@@ -119,10 +125,11 @@ dp83816_reset(dp83816_priv_data_t *dp)
     } while (((stat & _CR_RST) != 0) && (--timeout > 0));
     if (timeout == 0) {
         diag_printf("DP83816 - reset timed out! - stat: %x\n", stat);
         return false;
     }
+
     // Rx ring
     bdp = dp->rxnext = CYGARC_UNCACHED_ADDRESS(dp->rxd);
     bp = dp->rxbuf;
     for (i = 0; i < dp->rxnum; i++, bdp++) {
         bdp->next = (dp83816_bd_t *)CYG_CPU_TO_LE32(CYGARC_PHYSICAL_ADDRESS(bdp+1));
@@ -143,10 +150,11 @@ dp83816_reset(dp83816_priv_data_t *dp)
         bp += _DP83816_BUFSIZE;
     }
     bdp--;  bdp->next = (dp83816_bd_t *)CYG_CPU_TO_LE32(CYGARC_PHYSICAL_ADDRESS(dp->txd));
     DP_OUT(dp->base, DP_TXCFG, _TXCFG_ATP |
                                _TXCFG_MXDMA_128 |
+           /* _TXCFG_CSI | */
                                ((256/32)<<_TXCFG_FLTH_SHIFT) |
                                ((512/32)<<_TXCFG_DRTH_SHIFT));
     DP_OUT(dp->base, DP_TXDP, CYGARC_PHYSICAL_ADDRESS(dp->txd));
     dp->txbusy = 0;
     // Fill in ESA
@@ -167,21 +175,49 @@ static bool 
 dp83816_init(struct cyg_netdevtab_entry *tab)
 {
     struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
     dp83816_priv_data_t *dp = (dp83816_priv_data_t *)sc->driver_private;
     cyg_uint8 *base;
-    bool esa_ok;
+    bool esa_ok = false;
     unsigned char enaddr[6];
 
     DEBUG_FUNCTION();
 
     CYGHWR_NS_DP83816_PLF_INIT(dp);
     base = dp->base;
     if (!base) return false;  // No device found
 
+#ifdef CYGPKG_REDBOOT
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+    esa_ok = flash_get_config(dp->esa_key, enaddr, CONFIG_ESA);
+#endif
+#elif defined (CONFIG_ESA)
+    esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,         
+                                         dp->esa_key, enaddr, CONFIG_ESA);
+#endif
     // Get physical device address
-#ifdef CYGHWR_NS_DP83816_USE_EEPROM
+    // There are two different implementations due to parallel implementations.
+    // Both are included for backward compatibility, but
+    // the CYGHWR_DEVS_ETH_NS_DP83816_USE_EEPROM_ESA implementation is
+    // preferred simply because it is smaller.
+#if defined(CYGHWR_DEVS_ETH_NS_DP83816_USE_EEPROM_ESA)
+    if (!esa_ok)
+    {
+        // Read the ESA from the PMATCH receive filter register, which
+        // will have been initialised from the EEPROM.
+        cyg_uint32 rfcrdat;
+        cyg_ucount8 i;
+        for (i = 0;  i < 6;  i+=2) {
+            DP_OUT(dp->base, DP_RFCR, i);
+            DP_IN(dp->base, DP_RFDR, rfcrdat );
+            enaddr[i] = rfcrdat & 0xff;
+            enaddr[i+1] = (rfcrdat>>8) & 0xff;
+        }
+        esa_ok = true;
+    }
+#elif defined(CYGHWR_NS_DP83816_USE_EEPROM)
+    // This define (CYGHWR_NS_DP83816_USE_EEPROM) is deprecated.
     {
         cyg_uint16 t;
 
         t = (dp83816_eeprom_read(dp, 0x0006) >> 15)
             | (dp83816_eeprom_read(dp, 0x0007) << 1);
@@ -196,31 +232,28 @@ dp83816_init(struct cyg_netdevtab_entry 
         enaddr[4] = t & 0xFF;
         enaddr[5] = t >> 8;
         
         esa_ok =  true;
     }
-#else
-#ifdef CYGPKG_REDBOOT
-#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
-    esa_ok = flash_get_config(dp->esa_key, enaddr, CONFIG_ESA);
-#else
-    esa_ok = false;
-#endif
-#else
-    esa_ok = CYGACC_CALL_IF_FLASH_CFG_OP(CYGNUM_CALL_IF_FLASH_CFG_GET,         
-                                         dp->esa_key, enaddr, CONFIG_ESA);
-#endif
 #endif
     if (esa_ok) {
         memcpy(dp->enaddr, enaddr, sizeof(enaddr));
     } else {
         // Can't figure out ESA
         diag_printf("DP83816 - Warning! ESA unknown\n");
     }
 
+    //    DEBUG_FUNCTION();
+
     if (!dp83816_reset(dp)) return false;
 
+#if DEBUG & 8
+    diag_printf("DP83816 - ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
+                dp->enaddr[0], dp->enaddr[1], dp->enaddr[2],
+                dp->enaddr[3], dp->enaddr[4], dp->enaddr[5] );
+#endif
+    
 #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
     cyg_drv_interrupt_create(
         dp->interrupt,
         0,                       // Priority - unused
         (cyg_addrword_t)sc,      // Data item passed to ISR & DSR
@@ -229,10 +262,12 @@ dp83816_init(struct cyg_netdevtab_entry 
         &dp->interrupt_handle,   // handle to intr obj
         &dp->interrupt_object ); // space for int obj
 
     cyg_drv_interrupt_attach(dp->interrupt_handle);
     cyg_drv_interrupt_unmask(dp->interrupt);
+#elif defined(CYGPKG_REDBOOT)
+    cyg_drv_interrupt_unmask(dp->interrupt);    
 #endif
 
     // Initialize upper level driver
     (sc->funs->eth_drv->init)(sc, dp->enaddr);
 
@@ -304,17 +339,31 @@ dp83816_send(struct eth_drv_sc *sc, stru
             int total_len, unsigned long key)
 {
     struct dp83816_priv_data *dp = (struct dp83816_priv_data *)sc->driver_private;
     int i, len;
     unsigned char *data;
-    dp83816_bd_t *bdp = dp->txfill;
+    dp83816_bd_t *bdp;
+#if 0
+    cyg_uint32 ints;
+    cyg_drv_dsr_lock();
+    HAL_DISABLE_INTERRUPTS(ints);
+#endif
+    
+    bdp= dp->txfill;
 
     DEBUG_FUNCTION();
 
     len = total_len;
     if (len < IEEE_8023_MIN_FRAME) len = IEEE_8023_MIN_FRAME;
     data = (unsigned char *)CYGARC_VIRTUAL_ADDRESS(CYG_LE32_TO_CPU((unsigned long)bdp->buf));
+#if DEBUG & 1
+    if (!norecurse) {
+        norecurse=1;
+        diag_printf("send sg_len==%d, txbusy=%d, len=%d, total_len=%d\n", sg_len, dp->txbusy, len, total_len);
+        norecurse = 0;
+    }
+#endif
     for (i = 0;  i < sg_len;  i++) {
         memcpy(data, (unsigned char *)sg_list[i].buf, sg_list[i].len);
         data += sg_list[i].len;
     }
     bdp->key = key;
@@ -322,10 +371,14 @@ dp83816_send(struct eth_drv_sc *sc, stru
     dp->txbusy++;
     bdp = (dp83816_bd_t *)CYGARC_UNCACHED_ADDRESS(CYGARC_VIRTUAL_ADDRESS(CYG_LE32_TO_CPU((unsigned long)bdp->next)));
     dp->txfill = bdp;
     // Kick the device, in case it went idle
     DP_OUT(dp->base, DP_CR, _CR_TXE);
+#if 0
+    cyg_drv_dsr_unlock();
+    HAL_RESTORE_INTERRUPTS(ints);
+#endif
 }
 
 static void
 dp83816_TxEvent(struct eth_drv_sc *sc)
 {
@@ -394,11 +447,12 @@ dp83816_recv(struct eth_drv_sc *sc, stru
     unsigned char *data;
     int i;
 
     data = (unsigned char *)CYGARC_VIRTUAL_ADDRESS(CYG_LE32_TO_CPU((unsigned long)bdp->buf));
     for (i = 0;  i < sg_len;  i++) {
-        memcpy((void *)sg_list[i].buf, data, sg_list[i].len);
+        if( sg_list[i].buf )
+            memcpy((void *)sg_list[i].buf, data, sg_list[i].len);
         data += sg_list[i].len;
     }
 }
 
 static void
@@ -406,10 +460,11 @@ dp83816_warm_reset(struct eth_drv_sc *sc
 {
     struct dp83816_priv_data *dp = (struct dp83816_priv_data *)sc->driver_private;
     dp83816_bd_t *bdp;
     int i;
 
+    DEBUG_FUNCTION();
     // Free up any active Tx buffers
     bdp = CYGARC_UNCACHED_ADDRESS(dp->txd);
     for (i = 0; i < dp->txnum; i++, bdp++) {
         if (bdp->key) {
             (sc->funs->eth_drv->tx_done)(sc, bdp->key, 0);
@@ -424,35 +479,42 @@ static void
 dp83816_poll(struct eth_drv_sc *sc)
 {
     struct dp83816_priv_data *dp = (struct dp83816_priv_data *)sc->driver_private;
     unsigned long stat, cr_stat;
 
+#if defined(CYGPKG_REDBOOT)
+    cyg_drv_interrupt_acknowledge(dp->interrupt);
+#endif
+    
     DP_IN(dp->base, DP_ISR, stat);
     do {
         if ((stat & (_ISR_TXDESC|_ISR_TXOK)) != 0) {
             dp83816_TxEvent(sc);
         }
         if ((stat & (_ISR_RXDESC|_ISR_RXOK|_ISR_RXERR)) != 0) {
             dp83816_RxEvent(sc);
         }
         DP_IN(dp->base, DP_CR, cr_stat);
         if ((stat & (_ISR_HIBERR|_ISR_TXURN|_ISR_RXORN)) != 0) {            
-#if 0
+#if DEBUG & 2
             diag_printf("DP83816 - major error: %x, cmd_stat: %x\n", stat, cr_stat);
 #endif
             // Try to reset the device
             dp83816_warm_reset(sc);
         }
-        if (((cr_stat & _CR_RXE) == 0) ||
-            ((dp->txbusy > 1) && ((cr_stat & _CR_TXE) == 0))) {
 #if 0
+        if (((cr_stat & _CR_RXE) == 0) ||
+            ((dp->txbusy > 1) && ((cr_stat & _CR_TXE) == 0)))
+        {
+#if DEBUG & 2
             // What happened?
-            diag_printf("DP83816 went to lunch? - stat: %x/%x, txbusy: %x\n", cr_stat, stat, dp->txbusy);
+            diag_printf("DP83816 went to lunch? - stat: %x/%x, txbusy: %x, bdstat: %x\n", cr_stat, stat, dp->txbusy, dp->txint->stat);
 #endif
             // Try to reset the device
             dp83816_warm_reset(sc);
         }
+#endif
         DP_IN(dp->base, DP_ISR, stat);
     } while (stat != 0);
 #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
     CYGHWR_NS_DP83816_PLF_INT_CLEAR(dp);
 #endif

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