Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pcmcia bring in stabilization codes in freebsd PAO/b...



details:   https://anonhg.NetBSD.org/src/rev/289e09c87dd3
branches:  trunk
changeset: 481286:289e09c87dd3
user:      itojun <itojun%NetBSD.org@localhost>
date:      Tue Jan 25 16:48:47 2000 +0000

description:
bring in stabilization codes in freebsd PAO/bsdi cnw driver.
- link integrity bit check.
- don't send too many packets, add some delay between them (this one is
  not enabled by default - try it if you see performance problem on
  heavy traffic)

diffstat:

 sys/dev/pcmcia/if_cnw.c |  77 ++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 73 insertions(+), 4 deletions(-)

diffs (150 lines):

diff -r 372feec50f55 -r 289e09c87dd3 sys/dev/pcmcia/if_cnw.c
--- a/sys/dev/pcmcia/if_cnw.c   Tue Jan 25 16:24:40 2000 +0000
+++ b/sys/dev/pcmcia/if_cnw.c   Tue Jan 25 16:48:47 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_cnw.c,v 1.3 1999/11/29 12:53:59 itojun Exp $        */
+/*     $NetBSD: if_cnw.c,v 1.4 2000/01/25 16:48:47 itojun Exp $        */
 
 /*-
  * Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -163,6 +163,17 @@
 #endif
 int cnw_skey = CNW_SCRAMBLEKEY;                /* Scramble key */
 
+/*
+ * The card appears to work much better when we only allow one packet
+ * "in the air" at a time.  This is done by not allowing another packet
+ * on the card, even if there is room.  Turning this off will allow the
+ * driver to stuff packets on the card as soon as a transmit buffer is
+ * available.  This does increase the number of collisions, though.
+ * We can que a second packet if there are transmit buffers available,
+ * but we do not actually send the packet until the last packet has
+ * been written.
+#define        ONE_AT_A_TIME
+ */
 
 int    cnw_match __P((struct device *, struct cfdata *, void *));
 void   cnw_attach __P((struct device *, struct device *, void *));
@@ -186,6 +197,8 @@
        bus_space_tag_t sc_memt;            /*   ...bus_space tag */
        bus_space_handle_t sc_memh;         /*   ...bus_space handle */
        void *sc_ih;                        /* Interrupt cookie */
+       struct timeval sc_txlast;           /* When the last xmit was made */
+       int sc_active;                      /* Currently xmitting a packet */
 };
 
 struct cfattach cnw_ca = {
@@ -386,6 +399,7 @@
                return (EIO);
        }
        cnw_init(sc);
+       ifp->if_flags &= ~IFF_OACTIVE;
        ifp->if_flags |= IFF_RUNNING;
        return (0);
 }
@@ -528,14 +542,61 @@
 {
        struct cnw_softc *sc = ifp->if_softc;
        struct mbuf *m0;
+       int lif;
        int asr;
+#ifdef ONE_AT_A_TIME
+       struct timeval now;
+#endif
 
 #ifdef CNW_DEBUG
        if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
                printf("%s: cnw_start\n", ifp->if_xname);
+       if (ifp->if_flags & IFF_OACTIVE)
+               printf("%s: cnw_start reentered\n", ifp->if_xname);
 #endif
 
+       ifp->if_flags |= IFF_OACTIVE;
+
        for (;;) {
+#ifdef ONE_AT_A_TIME
+               microtime(&now);
+               now.tv_sec -= sc->sc_txlast.tv_sec;
+               now.tv_usec -= sc->sc_txlast.tv_usec;
+               if (now.tv_usec < 0) {
+                       now.tv_usec += 1000000;
+                       now.tv_sec--;
+               }
+
+               /*
+                * Don't ship this packet out until the last
+                * packet has left the building.
+                * If we have not tried to send a packet for 1/5
+                * a second then we assume we lost an interrupt,
+                * lets go on and send the next packet anyhow.
+                *
+                * I suppose we could check to see if it is okay
+                * to put additional packets on the card (beyond
+                * the one already waiting to be sent) but I don't
+                * think we would get any improvement in speed as
+                * we should have ample time to put the next packet
+                * on while this one is going out.
+                */
+               if (sc->sc_active && now.tv_sec == 0 && now.tv_usec < 200000)
+                       break;
+#endif
+
+               /* Make sure the link integrity field is on */
+               WAIT_WOC(sc);
+               lif = bus_space_read_1(sc->sc_memt, sc->sc_memh,
+                   sc->sc_memoff + CNW_EREG_LIF);
+               if (lif == 0) {
+#ifdef CNW_DEBUG
+                       if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
+                               printf("%s: link integrity %d\n", lif);
+#endif
+                       break;
+               }
+
                /* Is there any buffer space available on the card? */
                WAIT_WOC(sc);
                asr = bus_space_read_1(sc->sc_iot, sc->sc_ioh, CNW_REG_ASR);
@@ -544,14 +605,14 @@
                        if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG)
                                printf("%s: no buffer space\n", ifp->if_xname);
 #endif
-                       return;
+                       break;
                }
 
                sc->sc_stats.nws_tx++;
 
                IF_DEQUEUE(&ifp->if_snd, m0);
                if (m0 == 0)
-                       return;
+                       break;
 
 #if NBPFILTER > 0
                if (ifp->if_bpf)
@@ -561,10 +622,14 @@
                cnw_transmit(sc, m0);
                ++ifp->if_opackets;
                ifp->if_timer = 3; /* start watchdog timer */
+
+               microtime(&sc->sc_txlast);
+               sc->sc_active = 1;
        }
+
+       ifp->if_flags &= ~IFF_OACTIVE;
 }
 
-
 /*
  * Transmit a packet.
  */
@@ -868,6 +933,10 @@
                                    (tser & CNW_TSER_ERROR) |
                                    CNW_TSER_RTRY);
                        }
+
+                       sc->sc_active = 0;
+                       ifp->if_flags &= ~IFF_OACTIVE;
+
                        /* Continue to send packets from the queue */
                        cnw_start(&sc->sc_ethercom.ec_if);
                }



Home | Main Index | Thread Index | Old Index