Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/powerpc/booke/dev Fix various conditions with setti...



details:   https://anonhg.NetBSD.org/src/rev/30e56c87a585
branches:  trunk
changeset: 335580:30e56c87a585
user:      nonaka <nonaka%NetBSD.org@localhost>
date:      Fri Jan 16 07:48:16 2015 +0000

description:
Fix various conditions with setting IMASK.

diffstat:

 sys/arch/powerpc/booke/dev/pq3etsec.c |  71 ++++++++++++++++++++++++----------
 1 files changed, 50 insertions(+), 21 deletions(-)

diffs (204 lines):

diff -r 0aa2cf1b91ad -r 30e56c87a585 sys/arch/powerpc/booke/dev/pq3etsec.c
--- a/sys/arch/powerpc/booke/dev/pq3etsec.c     Fri Jan 16 06:38:27 2015 +0000
+++ b/sys/arch/powerpc/booke/dev/pq3etsec.c     Fri Jan 16 07:48:16 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pq3etsec.c,v 1.22 2015/01/16 06:38:27 nonaka Exp $     */
+/*     $NetBSD: pq3etsec.c,v 1.23 2015/01/16 07:48:16 nonaka Exp $     */
 /*-
  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -39,7 +39,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(0, "$NetBSD: pq3etsec.c,v 1.22 2015/01/16 06:38:27 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pq3etsec.c,v 1.23 2015/01/16 07:48:16 nonaka Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -212,6 +212,7 @@
        void *sc_soft_ih;
 
        kmutex_t *sc_lock;
+       kmutex_t *sc_hwlock;
 
        struct evcnt sc_ev_tx_stall;
        struct evcnt sc_ev_tx_intr;
@@ -617,14 +618,14 @@
 #endif
        }
 
-       char enaddr[ETHER_ADDR_LEN] = {
-           [0] = sc->sc_macstnaddr2 >> 16,
-           [1] = sc->sc_macstnaddr2 >> 24,
-           [2] = sc->sc_macstnaddr1 >>  0,
-           [3] = sc->sc_macstnaddr1 >>  8,
-           [4] = sc->sc_macstnaddr1 >> 16,
-           [5] = sc->sc_macstnaddr1 >> 24,
-       };
+       sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET);
+       sc->sc_hwlock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_VM);
+
+       callout_init(&sc->sc_mii_callout, CALLOUT_MPSAFE);
+       callout_setfunc(&sc->sc_mii_callout, pq3etsec_mii_tick, sc);
+
+       /* Disable interrupts */
+       etsec_write(sc, IMASK, 0);
 
        error = pq3etsec_rxq_attach(sc, &sc->sc_rxq, 0);
        if (error) {
@@ -704,11 +705,14 @@
        etsec_write(sc, ATTR, ATTR_DEFAULT);
        etsec_write(sc, ATTRELI, ATTRELI_DEFAULT);
 
-       sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_SOFTNET);
-
-       callout_init(&sc->sc_mii_callout, CALLOUT_MPSAFE);
-       callout_setfunc(&sc->sc_mii_callout, pq3etsec_mii_tick, sc);
-
+       char enaddr[ETHER_ADDR_LEN] = {
+           [0] = sc->sc_macstnaddr2 >> 16,
+           [1] = sc->sc_macstnaddr2 >> 24,
+           [2] = sc->sc_macstnaddr1 >>  0,
+           [3] = sc->sc_macstnaddr1 >>  8,
+           [4] = sc->sc_macstnaddr1 >> 16,
+           [5] = sc->sc_macstnaddr1 >> 24,
+       };
        aprint_normal_dev(sc->sc_dev, "Ethernet address %s\n",
           ether_sprintf(enaddr));
 
@@ -2261,6 +2265,10 @@
 {
        struct pq3etsec_softc * const sc = ifp->if_softc;
 
+       if (__predict_false((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)) {
+               return;
+       }
+
        atomic_or_uint(&sc->sc_soft_flags, SOFT_TXINTR);
        softint_schedule(sc->sc_soft_ih);
 }
@@ -2294,6 +2302,8 @@
 {
        struct pq3etsec_softc * const sc = arg;
 
+       mutex_enter(sc->sc_hwlock);
+
        sc->sc_ev_tx_intr.ev_count++;
 
        uint32_t ievent = etsec_read(sc, IEVENT);
@@ -2305,13 +2315,18 @@
            __func__, ievent, etsec_read(sc, IMASK));
 #endif
 
-       if (ievent == 0)
+       if (ievent == 0) {
+               mutex_exit(sc->sc_hwlock);
                return 0;
+       }
 
        sc->sc_imask &= ~(IEVENT_TXF|IEVENT_TXB);
        atomic_or_uint(&sc->sc_soft_flags, SOFT_TXINTR);
        etsec_write(sc, IMASK, sc->sc_imask);
        softint_schedule(sc->sc_soft_ih);
+
+       mutex_exit(sc->sc_hwlock);
+
        return 1;
 }
 
@@ -2320,13 +2335,17 @@
 {
        struct pq3etsec_softc * const sc = arg;
 
+       mutex_enter(sc->sc_hwlock);
+
        sc->sc_ev_rx_intr.ev_count++;
 
        uint32_t ievent = etsec_read(sc, IEVENT);
        ievent &= IEVENT_RXF|IEVENT_RXB;
        etsec_write(sc, IEVENT, ievent);        /* write 1 to clear */
-       if (ievent == 0)
+       if (ievent == 0) {
+               mutex_exit(sc->sc_hwlock);
                return 0;
+       }
 
 #if 0
        aprint_normal_dev(sc->sc_dev, "%s: ievent=%#x\n", __func__, ievent);
@@ -2336,6 +2355,9 @@
        atomic_or_uint(&sc->sc_soft_flags, SOFT_RXINTR);
        etsec_write(sc, IMASK, sc->sc_imask);
        softint_schedule(sc->sc_soft_ih);
+
+       mutex_exit(sc->sc_hwlock);
+
        return 1;
 }
 
@@ -2344,6 +2366,8 @@
 {
        struct pq3etsec_softc * const sc = arg;
 
+       mutex_enter(sc->sc_hwlock);
+
        sc->sc_ev_error_intr.ev_count++;
 
        for (int rv = 0, soft_flags = 0;; rv = 1) {
@@ -2355,6 +2379,7 @@
                                atomic_or_uint(&sc->sc_soft_flags, soft_flags);
                                softint_schedule(sc->sc_soft_ih);
                        }
+                       mutex_exit(sc->sc_hwlock);
                        return rv;
                }
 #if 0
@@ -2401,6 +2426,7 @@
 {
        struct pq3etsec_softc * const sc = arg;
        struct ifnet * const ifp = &sc->sc_if;
+       uint32_t imask = 0;
 
        mutex_enter(sc->sc_lock);
 
@@ -2421,7 +2447,7 @@
                if (threshold >= rxq->rxq_last - rxq->rxq_first) {
                        threshold = rxq->rxq_last - rxq->rxq_first - 1;
                } else {
-                       sc->sc_imask |= IEVENT_BSY;
+                       imask |= IEVENT_BSY;
                }
                aprint_normal_dev(sc->sc_dev,
                    "increasing receive buffers from %zu to %zu\n",
@@ -2442,7 +2468,7 @@
                } else {
                        ifp->if_flags &= ~IFF_OACTIVE;
                }
-               sc->sc_imask |= IEVENT_TXF;
+               imask |= IEVENT_TXF;
        }
 
        if (soft_flags & (SOFT_RXINTR|SOFT_RXBSY)) {
@@ -2450,17 +2476,20 @@
                 * Let's consume 
                 */
                pq3etsec_rxq_consume(sc, &sc->sc_rxq);
-               sc->sc_imask |= IEVENT_RXF;
+               imask |= IEVENT_RXF;
        }
 
        if (soft_flags & SOFT_TXERROR) {
                pq3etsec_tx_error(sc);
-               sc->sc_imask |= IEVENT_TXE;
+               imask |= IEVENT_TXE;
        }
 
        if (ifp->if_flags & IFF_RUNNING) {
                pq3etsec_rxq_produce(sc, &sc->sc_rxq);
+               mutex_spin_enter(sc->sc_hwlock);
+               sc->sc_imask |= imask;
                etsec_write(sc, IMASK, sc->sc_imask);
+               mutex_spin_exit(sc->sc_hwlock);
        } else {
                KASSERT((soft_flags & SOFT_RXBSY) == 0);
        }



Home | Main Index | Thread Index | Old Index