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]

ETH - improve error handling on NS/DP83816


Somewhat - it still sometimes just stops and has to be reset.

-- 
Gary Thomas <gary@mlbassoc.com>
MLB Associates
Index: devs/eth/ns/dp83816/current/ChangeLog
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/devs/eth/ns/dp83816/current/ChangeLog,v
retrieving revision 1.2
diff -u -5 -p -r1.2 ChangeLog
--- devs/eth/ns/dp83816/current/ChangeLog	2 Oct 2003 20:11:57 -0000	1.2
+++ devs/eth/ns/dp83816/current/ChangeLog	14 Oct 2003 13:24:43 -0000
@@ -1,5 +1,12 @@
+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
+	detect the condition and then reset/restart the device.
+
 2003-10-02  Gary Thomas  <gary@mlbassoc.com>
 
 	* src/dp83816.h: Let default ESA be a pointer, so platforms can more
 	easily set it a runtime.
 
Index: devs/eth/ns/dp83816/current/src/if_dp83816.c
===================================================================
RCS file: /misc/cvsfiles/ecos/packages/devs/eth/ns/dp83816/current/src/if_dp83816.c,v
retrieving revision 1.2
diff -u -5 -p -r1.2 if_dp83816.c
--- devs/eth/ns/dp83816/current/src/if_dp83816.c	30 Sep 2003 21:10:11 -0000	1.2
+++ devs/eth/ns/dp83816/current/src/if_dp83816.c	14 Oct 2003 13:25:29 -0000
@@ -328,16 +328,20 @@ static void
 dp83816_RxEvent(struct eth_drv_sc *sc)
 {
     struct dp83816_priv_data *dp = (struct dp83816_priv_data *)sc->driver_private;
     dp83816_bd_t *bdp = CYGARC_UNCACHED_ADDRESS(dp->rxd);
     dp83816_bd_t *bdfirst = CYGARC_UNCACHED_ADDRESS(dp->rxd);
-    int len;
+    int len, err;
 
     DEBUG_FUNCTION();
 
     while (true) {
         if ((_le2h(bdp->stat) & BD_OWN) != 0) {
+            err = _le2h(bdp->stat) & (BD_RXA|BD_RXO|BD_LONG|BD_RUNT|BD_ISE|BD_CRCE|BD_FAE|BD_COL);
+            if (err != 0) {
+                diag_printf("RxError: %x\n", err);
+            }
             len = _le2h(bdp->stat) & BD_LENGTH_MASK;
             dp->rxnext = bdp;
             (sc->funs->eth_drv->recv)(sc, len);
             bdp->stat = _h2le(BD_INTR | _DP83816_BUFSIZE);  // Give back buffer
         }
@@ -369,53 +373,57 @@ dp83816_recv(struct eth_drv_sc *sc, stru
         data += sg_list[i].len;
     }
 }
 
 static void
-dp83816_poll(struct eth_drv_sc *sc)
+dp83816_warm_reset(struct eth_drv_sc *sc)
 {
     struct dp83816_priv_data *dp = (struct dp83816_priv_data *)sc->driver_private;
-    unsigned long stat, cr_stat;
     dp83816_bd_t *bdp;
+    int len, err;
     int i;
 
+    // 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);
+        }
+    }
+    // Reset the device
+    dp83816_reset(dp);
+    DP_OUT(dp->base, DP_CR, _CR_RXE | _CR_TXE);
+}
+
+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;
+
     DP_IN(dp->base, DP_ISR, stat);
     do {
         if ((stat & (_ISR_TXDESC|_ISR_TXOK)) != 0) {
             dp83816_TxEvent(sc);
         }
-        if ((stat & (_ISR_RXDESC|_ISR_RXOK)) != 0) {
+        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) {            
-            diag_printf("DP83816 - major error: %x", stat);
-            DP_IN(dp->base, DP_CR, stat);
-            diag_printf(", cmd: %x\n", stat);
+            diag_printf("DP83816 - major error: %x, cmd_stat: %x\n", stat, cr_stat);
             // Try to reset the device
-            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);
-                }
-            }
-            dp83816_reset(dp);
-            DP_OUT(dp->base, DP_CR, _CR_RXE | _CR_TXE);
+            dp83816_warm_reset(sc);
         }
-        DP_IN(dp->base, DP_CR, cr_stat);
         if (((cr_stat & _CR_RXE) == 0) ||
             ((dp->txbusy > 1) && ((cr_stat & _CR_TXE) == 0))) {
+#if 0
             // What happened?
-            diag_printf("DP83816 went to lunch? - stat: %x, txbusy: %x\n", cr_stat, dp->txbusy);
+            diag_printf("DP83816 went to lunch? - stat: %x/%x, txbusy: %x\n", cr_stat, stat, dp->txbusy);
+#endif
             // Try to reset the device
-            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);
-                }
-            }
-            dp83816_reset(dp);
-            DP_OUT(dp->base, DP_CR, _CR_RXE | _CR_TXE);
+            dp83816_warm_reset(sc);
         }
         DP_IN(dp->base, DP_ISR, stat);
     } while (stat != 0);
 #ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
     CYGHWR_NS_DP83816_PLF_INT_CLEAR(dp);

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