The recent mii_tick diff made me ponder whether the mii tick timeout could be put in the mii_data struct rather than each driver softc (not that a good idea, actually).
While looking at this, I noticed that two drivers may end up invoking mii_tick() while not being at IPL_NET. bnx: bnx_tick() can get invoked either from the interrupt handler, or from a timeout. sk: on some boards, sk_tick() gets invoked from timeout, but may end up invoking sk_intr_bcom() which is intended to run at IPL_NET. This diff has only been compile-tested, for lack of such hardware. Index: if_bnx.c =================================================================== RCS file: /OpenBSD/src/sys/dev/pci/if_bnx.c,v retrieving revision 1.125 diff -u -p -r1.125 if_bnx.c --- if_bnx.c 10 Mar 2018 10:51:46 -0000 1.125 +++ if_bnx.c 3 Jul 2019 06:40:47 -0000 @@ -5457,6 +5457,9 @@ bnx_tick(void *xsc) struct ifnet *ifp = &sc->arpcom.ac_if; struct mii_data *mii = NULL; u_int32_t msg; + int s; + + s = splnet(); /* Tell the firmware that the driver is still running. */ #ifdef BNX_DEBUG @@ -5489,7 +5492,7 @@ bnx_tick(void *xsc) } bnx_tick_exit: - return; + splx(s); } /****************************************************************************/ Index: if_sk.c =================================================================== RCS file: /OpenBSD/src/sys/dev/pci/if_sk.c,v retrieving revision 1.189 diff -u -p -r1.189 if_sk.c --- if_sk.c 4 Jun 2017 04:29:23 -0000 1.189 +++ if_sk.c 3 Jul 2019 06:40:47 -0000 @@ -1703,15 +1703,20 @@ sk_tick(void *xsc_if) struct sk_if_softc *sc_if = xsc_if; struct mii_data *mii = &sc_if->sk_mii; struct ifnet *ifp = &sc_if->arpcom.ac_if; - int i; + int i, s; DPRINTFN(2, ("sk_tick\n")); - if (!(ifp->if_flags & IFF_UP)) + s = splnet(); + + if (!(ifp->if_flags & IFF_UP)) { + splx(s); return; + } if (sc_if->sk_phytype == SK_PHYTYPE_BCOM) { sk_intr_bcom(sc_if); + splx(s); return; } @@ -1729,6 +1734,7 @@ sk_tick(void *xsc_if) if (i != 3) { timeout_add_sec(&sc_if->sk_tick_ch, 1); + splx(s); return; } @@ -1736,6 +1742,7 @@ sk_tick(void *xsc_if) SK_XM_CLRBIT_2(sc_if, XM_IMR, XM_IMR_GP0_SET); SK_XM_READ_2(sc_if, XM_ISR); mii_tick(mii); + splx(s); timeout_del(&sc_if->sk_tick_ch); }