Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/ic Fix a couple of problems with MII-equipped NE2000...



details:   https://anonhg.NetBSD.org/src/rev/e496d3df1493
branches:  trunk
changeset: 380015:e496d3df1493
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Wed Jun 30 20:00:18 2021 +0000

description:
Fix a couple of problems with MII-equipped NE2000 derivatives reported by
Björn Johannesson on current-users@:

- Re-factor dp8390_stop() into dp8390_halt() (that does the stuff to
  halt the hardware) and dp8390_stop() (which alls dp8390_halt() before
  calling mii_down() via sc->sc_stop_card()).  This prevents us from
  calling mii_down() before all of the interface data structures have
  been set up, which these days can trip a KASSERT().

- Add a 1-second timer to call mii_tick(), and enable it in the
  sc->sc_init_card() callback, and cancel it in the sc->sc_stop_card()
  and sc->sc_media_fini() callbacks.  This is actually a long-standing
  bug that previously didn't have much practical effect, but causes
  problems with dhcpcd's link live-ness detection logic.

diffstat:

 sys/dev/ic/ax88190.c   |  24 +++++++++++++++++++++---
 sys/dev/ic/dl10019.c   |  24 +++++++++++++++++++++---
 sys/dev/ic/dp8390.c    |  19 ++++++++++++++-----
 sys/dev/ic/dp8390var.h |   4 +++-
 4 files changed, 59 insertions(+), 12 deletions(-)

diffs (231 lines):

diff -r d0fa5570297b -r e496d3df1493 sys/dev/ic/ax88190.c
--- a/sys/dev/ic/ax88190.c      Wed Jun 30 17:51:49 2021 +0000
+++ b/sys/dev/ic/ax88190.c      Wed Jun 30 20:00:18 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ax88190.c,v 1.16 2020/02/04 05:25:39 thorpej Exp $     */
+/*     $NetBSD: ax88190.c,v 1.17 2021/06/30 20:00:18 thorpej Exp $     */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ax88190.c,v 1.16 2020/02/04 05:25:39 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ax88190.c,v 1.17 2021/06/30 20:00:18 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -80,12 +80,27 @@ static const struct mii_bitbang_ops ax88
        }
 };
 
+static void
+ax88190_tick(void *arg)
+{
+       struct dp8390_softc *sc = arg;
+       int s;
+
+       s = splnet();
+       mii_tick(&sc->sc_mii);
+       splx(s);
+
+       callout_schedule(&sc->sc_tick_ch, hz);
+}
+
 void
 ax88190_media_init(struct dp8390_softc *sc)
 {
        struct ifnet *ifp = &sc->sc_ec.ec_if;
        struct mii_data *mii = &sc->sc_mii;
 
+       callout_setfunc(&sc->sc_tick_ch, ax88190_tick, sc);
+
        mii->mii_ifp = ifp;
        mii->mii_readreg = ax88190_mii_readreg;
        mii->mii_writereg = ax88190_mii_writereg;
@@ -107,8 +122,9 @@ void
 ax88190_media_fini(struct dp8390_softc *sc)
 {
 
+       callout_stop(&sc->sc_tick_ch);
        mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
-       ifmedia_fini(&sc->sc_mii.mii_media);
+       /* dp8390_detach() will call ifmedia_fini(). */
 }
 
 int
@@ -135,12 +151,14 @@ ax88190_init_card(struct dp8390_softc *s
 {
 
        mii_mediachg(&sc->sc_mii);
+       callout_schedule(&sc->sc_tick_ch, hz);
 }
 
 void
 ax88190_stop_card(struct dp8390_softc *sc)
 {
 
+       callout_stop(&sc->sc_tick_ch);
        mii_down(&sc->sc_mii);
 }
 
diff -r d0fa5570297b -r e496d3df1493 sys/dev/ic/dl10019.c
--- a/sys/dev/ic/dl10019.c      Wed Jun 30 17:51:49 2021 +0000
+++ b/sys/dev/ic/dl10019.c      Wed Jun 30 20:00:18 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dl10019.c,v 1.15 2020/02/04 05:25:39 thorpej Exp $     */
+/*     $NetBSD: dl10019.c,v 1.16 2021/06/30 20:00:18 thorpej Exp $     */
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dl10019.c,v 1.15 2020/02/04 05:25:39 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dl10019.c,v 1.16 2021/06/30 20:00:18 thorpej Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -113,12 +113,27 @@ dl10019_mii_reset(struct dp8390_softc *s
        bus_space_write_1(sc->sc_regt, sc->sc_regh, NEDL_DL0_GPIO, 0x00);
 }
 
+static void
+dl10019_tick(void *arg)
+{
+       struct dp8390_softc *sc = arg;
+       int s;
+
+       s = splnet();
+       mii_tick(&sc->sc_mii);
+       splx(s);
+
+       callout_schedule(&sc->sc_tick_ch, hz);
+}
+
 void
 dl10019_media_init(struct dp8390_softc *sc)
 {
        struct ifnet *ifp = &sc->sc_ec.ec_if;
        struct mii_data *mii = &sc->sc_mii;
 
+       callout_setfunc(&sc->sc_tick_ch, dl10019_tick, sc);
+
        mii->mii_ifp = ifp;
        mii->mii_readreg = dl10019_mii_readreg;
        mii->mii_writereg = dl10019_mii_writereg;
@@ -142,8 +157,9 @@ void
 dl10019_media_fini(struct dp8390_softc *sc)
 {
 
+       callout_stop(&sc->sc_tick_ch);
        mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY);
-       ifmedia_fini(&sc->sc_mii.mii_media);
+       /* dp8390_detach() will call ifmedia_fini(). */
 }
 
 int
@@ -171,12 +187,14 @@ dl10019_init_card(struct dp8390_softc *s
 
        dl10019_mii_reset(sc);
        mii_mediachg(&sc->sc_mii);
+       callout_schedule(&sc->sc_tick_ch, hz);
 }
 
 void
 dl10019_stop_card(struct dp8390_softc *sc)
 {
 
+       callout_stop(&sc->sc_tick_ch);
        mii_down(&sc->sc_mii);
 }
 
diff -r d0fa5570297b -r e496d3df1493 sys/dev/ic/dp8390.c
--- a/sys/dev/ic/dp8390.c       Wed Jun 30 17:51:49 2021 +0000
+++ b/sys/dev/ic/dp8390.c       Wed Jun 30 20:00:18 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dp8390.c,v 1.97 2020/02/04 05:25:39 thorpej Exp $      */
+/*     $NetBSD: dp8390.c,v 1.98 2021/06/30 20:00:18 thorpej Exp $      */
 
 /*
  * Device driver for National Semiconductor DS8390/WD83C690 based ethernet
@@ -14,7 +14,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dp8390.c,v 1.97 2020/02/04 05:25:39 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dp8390.c,v 1.98 2021/06/30 20:00:18 thorpej Exp $");
 
 #include "opt_inet.h"
 
@@ -51,6 +51,8 @@
 int    dp8390_debug = 0;
 #endif
 
+static void    dp8390_halt(struct dp8390_softc *);
+
 static void dp8390_xmit(struct dp8390_softc *);
 
 static void dp8390_read_hdr(struct dp8390_softc *, int, struct dp8390_ring *);
@@ -115,7 +117,9 @@ dp8390_config(struct dp8390_softc *sc)
                goto out;
 
        /* Set interface to stopped condition (reset). */
-       dp8390_stop(sc);
+       dp8390_halt(sc);
+
+       callout_init(&sc->sc_tick_ch, 0);
 
        /* Initialize ifnet structure. */
        strcpy(ifp->if_xname, device_xname(sc->sc_dev));
@@ -201,8 +205,8 @@ dp8390_reset(struct dp8390_softc *sc)
 /*
  * Take interface offline.
  */
-void
-dp8390_stop(struct dp8390_softc *sc)
+static void
+dp8390_halt(struct dp8390_softc *sc)
 {
        bus_space_tag_t regt = sc->sc_regt;
        bus_space_handle_t regh = sc->sc_regh;
@@ -221,7 +225,12 @@ dp8390_stop(struct dp8390_softc *sc)
         */
        while (((NIC_GET(regt, regh, ED_P0_ISR) & ED_ISR_RST) == 0) && --n)
                DELAY(1);
+}
 
+void
+dp8390_stop(struct dp8390_softc *sc)
+{
+       dp8390_halt(sc);
        if (sc->stop_card != NULL)
                (*sc->stop_card)(sc);
 }
diff -r d0fa5570297b -r e496d3df1493 sys/dev/ic/dp8390var.h
--- a/sys/dev/ic/dp8390var.h    Wed Jun 30 17:51:49 2021 +0000
+++ b/sys/dev/ic/dp8390var.h    Wed Jun 30 20:00:18 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: dp8390var.h,v 1.34 2018/07/15 05:16:45 maxv Exp $      */
+/*     $NetBSD: dp8390var.h,v 1.35 2021/06/30 20:00:18 thorpej Exp $   */
 
 /*
  * Device driver for National Semiconductor DS8390/WD83C690 based ethernet
@@ -19,6 +19,7 @@
  * We include MII glue here -- some DP8390 compatible chips have
  * MII interfaces on them (scary, isn't it...).
  */
+#include <sys/callout.h>
 #include <dev/mii/miivar.h>
 
 #define INTERFACE_NAME_LEN     32
@@ -34,6 +35,7 @@ struct dp8390_softc {
        struct ethercom sc_ec;          /* ethernet common */
        struct mii_data sc_mii;         /* MII glue */
 #define        sc_media sc_mii.mii_media       /* compatibilty definition */
+       callout_t       sc_tick_ch;     /* MII tick callout */
 
        bus_space_tag_t sc_regt;        /* NIC register space tag */
        bus_space_handle_t sc_regh;     /* NIC register space handle */



Home | Main Index | Thread Index | Old Index