Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci Rework transmit underrun logic:



details:   https://anonhg.NetBSD.org/src/rev/80f4ad706a75
branches:  trunk
changeset: 532341:80f4ad706a75
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Wed Jun 05 15:24:31 2002 +0000

description:
Rework transmit underrun logic:
- when a transmit underrun occurs, only reset the transmit logic. This prevents
  the link from going down at the MII level (the same logic can probably
  be used for other transmit errors)
- set the urgent threshold to half the start threshold. From experiments
  this helps a bit decreasing the number of underruns

Now that underruns don't cause the interface to stop for several seconds,
make back out the default transmit threshold to 128.

diffstat:

 sys/dev/pci/if_ste.c |  90 ++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 74 insertions(+), 16 deletions(-)

diffs (175 lines):

diff -r 81ed5b22a25d -r 80f4ad706a75 sys/dev/pci/if_ste.c
--- a/sys/dev/pci/if_ste.c      Wed Jun 05 15:14:16 2002 +0000
+++ b/sys/dev/pci/if_ste.c      Wed Jun 05 15:24:31 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_ste.c,v 1.9 2002/06/01 17:24:38 bouyer Exp $        */
+/*     $NetBSD: if_ste.c,v 1.10 2002/06/05 15:24:31 bouyer Exp $       */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ste.c,v 1.9 2002/06/01 17:24:38 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ste.c,v 1.10 2002/06/05 15:24:31 bouyer Exp $");
 
 #include "bpfilter.h"
 
@@ -212,7 +212,9 @@
 
 void   ste_shutdown(void *);
 
-void   ste_reset(struct ste_softc *);
+void   ste_reset(struct ste_softc *, u_int32_t);
+void   ste_setthresh(struct ste_softc *);
+void   ste_txrestart(struct ste_softc *, u_int8_t);
 void   ste_rxdrain(struct ste_softc *);
 int    ste_add_rxbuf(struct ste_softc *, int);
 void   ste_read_eeprom(struct ste_softc *, int, uint16_t *);
@@ -461,7 +463,8 @@
        /*
         * Reset the chip to a known state.
         */
-       ste_reset(sc);
+       ste_reset(sc, AC_GlobalReset | AC_RxReset | AC_TxReset | AC_DMA |
+           AC_FIFO | AC_Network | AC_Host | AC_AutoInit | AC_RstOut);
 
        /*
         * Read the Ethernet address from the EEPROM.
@@ -504,9 +507,9 @@
        IFQ_SET_READY(&ifp->if_snd);
 
        /*
-        * Default the transmit threshold to 1504 bytes.
+        * Default the transmit threshold to 128 bytes.
         */
-       sc->sc_txthresh = 1504;
+       sc->sc_txthresh = 128;
 
        /*
         * Disable MWI if the PCI layer tells us to.
@@ -891,17 +894,33 @@
                                            "threshold: %d bytes\n",
                                            sc->sc_dev.dv_xname,
                                            sc->sc_txthresh);
+                                       ste_reset(sc, AC_TxReset | AC_DMA |
+                                           AC_FIFO | AC_Network);
+                                       ste_setthresh(sc);
+                                       bus_space_write_1(sc->sc_st, sc->sc_sh,
+                                           STE_TxDMAPollPeriod, 127);
+                                       ste_txrestart(sc,
+                                           bus_space_read_1(sc->sc_st,
+                                               sc->sc_sh, STE_TxFrameId));
                                }
-                               if (txstat & TS_TxReleaseError)
+                               if (txstat & TS_TxReleaseError) {
                                        printf("%s: Tx FIFO release error\n",
                                            sc->sc_dev.dv_xname);
-                               if (txstat & TS_MaxCollisions)
+                                       wantinit = 1;
+                               }
+                               if (txstat & TS_MaxCollisions) {
                                        printf("%s: excessive collisions\n",
                                            sc->sc_dev.dv_xname);
+                                       wantinit = 1;
+                               }
+                               if (txstat & TS_TxStatusOverflow) {
+                                       printf("%s: status overflow\n",
+                                           sc->sc_dev.dv_xname);
+                                       wantinit = 1;
+                               }
                                bus_space_write_2(sc->sc_st, sc->sc_sh,
                                    STE_TxStatus, 0);
                        }
-                       wantinit = 1;
                }
 
                /* Host interface errors. */
@@ -1142,17 +1161,14 @@
  *     Perform a soft reset on the ST-201.
  */
 void
-ste_reset(struct ste_softc *sc)
+ste_reset(struct ste_softc *sc, u_int32_t rstbits)
 {
        uint32_t ac;
        int i;
 
        ac = bus_space_read_4(sc->sc_st, sc->sc_sh, STE_AsicCtrl);
 
-       bus_space_write_4(sc->sc_st, sc->sc_sh, STE_AsicCtrl,
-           ac | AC_GlobalReset | AC_RxReset | AC_TxReset |
-           AC_DMA | AC_FIFO | AC_Network | AC_Host | AC_AutoInit |
-           AC_RstOut);
+       bus_space_write_4(sc->sc_st, sc->sc_sh, STE_AsicCtrl, ac | rstbits);
 
        delay(50000);
 
@@ -1170,6 +1186,47 @@
 }
 
 /*
+ * ste_setthresh:
+ *
+ *     set the various transmit threshold registers
+ */
+void
+ste_setthresh(struct ste_softc *sc)
+{
+       /* set the TX threhold */
+       bus_space_write_2(sc->sc_st, sc->sc_sh,
+           STE_TxStartThresh, sc->sc_txthresh);
+       /* Urgent threshold: set to sc_txthresh / 2 */
+       bus_space_write_2(sc->sc_st, sc->sc_sh, STE_TxDMAUrgentThresh,
+           sc->sc_txthresh >> 6);
+       /* Burst threshold: use default value (256 bytes) */
+}
+
+/*
+ * restart TX at the given frame ID in the transmitter ring
+ */
+
+void
+ste_txrestart(struct ste_softc *sc, u_int8_t id)
+{
+       u_int32_t control;
+
+       STE_CDTXSYNC(sc, id, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
+       control = le32toh(sc->sc_txdescs[id].tfd_control);
+       control &= ~TFD_TxDMAComplete;
+       sc->sc_txdescs[id].tfd_control = htole32(control);
+       STE_CDTXSYNC(sc, id, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
+
+       bus_space_write_4(sc->sc_st, sc->sc_sh, STE_TxDMAListPtr, 0);
+       bus_space_write_2(sc->sc_st, sc->sc_sh, STE_MacCtrl1, MC1_TxEnable);
+       bus_space_write_4(sc->sc_st, sc->sc_sh, STE_DMACtrl, DC_TxDMAHalt);
+       ste_dmahalt_wait(sc);
+       bus_space_write_4(sc->sc_st, sc->sc_sh, STE_TxDMAListPtr,
+           STE_CDTXADDR(sc, id));
+       bus_space_write_4(sc->sc_st, sc->sc_sh, STE_DMACtrl, DC_TxDMAResume);
+}
+
+/*
  * ste_init:           [ ifnet interface function ]
  *
  *     Initialize the interface.  Must be called at splnet().
@@ -1191,7 +1248,8 @@
        /*
         * Reset the chip to a known state.
         */
-       ste_reset(sc);
+       ste_reset(sc, AC_GlobalReset | AC_RxReset | AC_TxReset | AC_DMA |
+           AC_FIFO | AC_Network | AC_Host | AC_AutoInit | AC_RstOut);
 
        /*
         * Initialize the transmit descriptor ring.
@@ -1255,7 +1313,7 @@
        bus_space_write_1(st, sh, STE_RxDMAPollPeriod, 64);
 
        /* Initialize the Tx start threshold. */
-       bus_space_write_2(st, sh, STE_TxStartThresh, sc->sc_txthresh);
+       ste_setthresh(sc);
 
        /* Set the FIFO release threshold to 512 bytes. */
        bus_space_write_1(st, sh, STE_TxReleaseThresh, 512 >> 4);



Home | Main Index | Thread Index | Old Index