Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci newstate should be blocked network interrupt, be...



details:   https://anonhg.NetBSD.org/src/rev/e8f5f9223dd6
branches:  trunk
changeset: 821003:e8f5f9223dd6
user:      nonaka <nonaka%NetBSD.org@localhost>
date:      Thu Jan 19 11:24:05 2017 +0000

description:
newstate should be blocked network interrupt, because it called iwm_start.

diffstat:

 sys/dev/pci/if_iwm.c |  94 ++++++++++++++++++++++++++++-----------------------
 1 files changed, 51 insertions(+), 43 deletions(-)

diffs (240 lines):

diff -r 46f766c40491 -r e8f5f9223dd6 sys/dev/pci/if_iwm.c
--- a/sys/dev/pci/if_iwm.c      Thu Jan 19 11:10:38 2017 +0000
+++ b/sys/dev/pci/if_iwm.c      Thu Jan 19 11:24:05 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_iwm.c,v 1.64 2017/01/17 08:47:32 nonaka Exp $       */
+/*     $NetBSD: if_iwm.c,v 1.65 2017/01/19 11:24:05 nonaka Exp $       */
 /*     OpenBSD: if_iwm.c,v 1.148 2016/11/19 21:07:08 stsp Exp  */
 #define IEEE80211_NO_HT
 /*
@@ -107,7 +107,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.64 2017/01/17 08:47:32 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_iwm.c,v 1.65 2017/01/19 11:24:05 nonaka Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -453,6 +453,8 @@
 static int     iwm_setrates(struct iwm_node *);
 #endif
 static int     iwm_media_change(struct ifnet *);
+static int     iwm_do_newstate(struct ieee80211com *, enum ieee80211_state,
+                   int);
 static void    iwm_newstate_cb(struct work *, void *);
 static int     iwm_newstate(struct ieee80211com *, enum ieee80211_state, int);
 static void    iwm_endscan(struct iwm_softc *);
@@ -2706,7 +2708,6 @@
                        sc->sc_rx_ba_sessions--;
        } else if (start)
                ieee80211_addba_req_refuse(ic, ni, tid);
-
        splx(s);
 }
 
@@ -3750,7 +3751,8 @@
                sc->qfullmsk &= ~(1 << qid);
                if (sc->qfullmsk == 0 && (ifp->if_flags & IFF_OACTIVE)) {
                        ifp->if_flags &= ~IFF_OACTIVE;
-                       if_start_lock(ifp);
+                       KASSERT(KERNEL_LOCKED_P());
+                       iwm_start(ifp);
                }
        }
 
@@ -5837,31 +5839,15 @@
        return err;
 }
 
-static void
-iwm_newstate_cb(struct work *wk, void *v)
-{
-       struct iwm_softc *sc = v;
-       struct ieee80211com *ic = &sc->sc_ic;
-       struct iwm_newstate_state *iwmns = (struct iwm_newstate_state *)wk;
-       enum ieee80211_state nstate = iwmns->ns_nstate;
+static int
+iwm_do_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
+{
+       struct ifnet *ifp = IC2IFP(ic);
+       struct iwm_softc *sc = ifp->if_softc;
        enum ieee80211_state ostate = ic->ic_state;
-       int generation = iwmns->ns_generation;
        struct iwm_node *in;
-       int arg = iwmns->ns_arg;
        int err;
 
-       kmem_free(iwmns, sizeof(*iwmns));
-
-       DPRINTF(("Prepare to switch state %d->%d\n", ostate, nstate));
-       if (sc->sc_generation != generation) {
-               DPRINTF(("newstate_cb: someone pulled the plug meanwhile\n"));
-               if (nstate == IEEE80211_S_INIT) {
-                       DPRINTF(("newstate_cb: nstate == IEEE80211_S_INIT: calling sc_newstate()\n"));
-                       sc->sc_newstate(ic, nstate, arg);
-               }
-               return;
-       }
-
        DPRINTF(("switching state %s->%s\n", ieee80211_state_name[ostate],
            ieee80211_state_name[nstate]));
 
@@ -5900,26 +5886,26 @@
        case IEEE80211_S_SCAN:
                if (ostate == nstate &&
                    ISSET(sc->sc_flags, IWM_FLAG_SCANNING))
-                       return;
+                       return 0;
                if (isset(sc->sc_enabled_capa, IWM_UCODE_TLV_CAPA_UMAC_SCAN))
                        err = iwm_umac_scan(sc);
                else
                        err = iwm_lmac_scan(sc);
                if (err) {
                        DPRINTF(("%s: could not initiate scan\n", DEVNAME(sc)));
-                       return;
+                       return err;
                }
                SET(sc->sc_flags, IWM_FLAG_SCANNING);
                ic->ic_state = nstate;
                iwm_led_blink_start(sc);
-               return;
+               return 0;
 
        case IEEE80211_S_AUTH:
                err = iwm_auth(sc);
                if (err) {
                        DPRINTF(("%s: could not move to auth state: %d\n",
                            DEVNAME(sc), err));
-                       return;
+                       return err;
                }
                break;
 
@@ -5928,7 +5914,7 @@
                if (err) {
                        DPRINTF(("%s: failed to associate: %d\n", DEVNAME(sc),
                            err));
-                       return;
+                       return err;
                }
                break;
 
@@ -5939,14 +5925,14 @@
                err = iwm_mac_ctxt_cmd(sc, in, IWM_FW_CTXT_ACTION_MODIFY, 1);
                if (err) {
                        aprint_error_dev(sc->sc_dev, "failed to update MAC\n");
-                       return;
+                       return err;
                }
 
                err = iwm_power_update_device(sc);
                if (err) {
                        aprint_error_dev(sc->sc_dev,
                            "could send power command (error %d)\n", err);
-                       return;
+                       return err;
                }
 #ifdef notyet
                /*
@@ -5958,21 +5944,21 @@
                if (err) {
                        aprint_error_dev(sc->sc_dev,
                            "could not enable beacon filter\n");
-                       return;
+                       return err;
                }
 #endif
                err = iwm_power_mac_update_mode(sc, in);
                if (err) {
                        aprint_error_dev(sc->sc_dev,
                            "could not update MAC power (error %d)\n", err);
-                       return;
+                       return err;
                }
 
                err = iwm_update_quotas(sc, in);
                if (err) {
                        aprint_error_dev(sc->sc_dev,
                            "could not update quotas (error %d)\n", err);
-                       return;
+                       return err;
                }
 
                ieee80211_amrr_node_init(&sc->sc_amrr, &in->in_amn);
@@ -5992,7 +5978,36 @@
                break;
        }
 
-       sc->sc_newstate(ic, nstate, arg);
+       return sc->sc_newstate(ic, nstate, arg);
+}
+
+static void
+iwm_newstate_cb(struct work *wk, void *v)
+{
+       struct iwm_softc *sc = v;
+       struct ieee80211com *ic = &sc->sc_ic;
+       struct iwm_newstate_state *iwmns = (struct iwm_newstate_state *)wk;
+       enum ieee80211_state nstate = iwmns->ns_nstate;
+       int generation = iwmns->ns_generation;
+       int arg = iwmns->ns_arg;
+       int s;
+
+       kmem_free(iwmns, sizeof(*iwmns));
+
+       s = splnet();
+
+       DPRINTF(("Prepare to switch state %d->%d\n", ic->ic_state, nstate));
+       if (sc->sc_generation != generation) {
+               DPRINTF(("newstate_cb: someone pulled the plug meanwhile\n"));
+               if (nstate == IEEE80211_S_INIT) {
+                       DPRINTF(("newstate_cb: nstate == IEEE80211_S_INIT: "
+                           "calling sc_newstate()\n"));
+                       (void) sc->sc_newstate(ic, nstate, arg);
+               }
+       } else
+               (void) iwm_do_newstate(ic, nstate, arg);
+
+       splx(s);
 }
 
 static int
@@ -6419,7 +6434,6 @@
 {
        struct iwm_softc *sc = ifp->if_softc;
        int err;
-       int s;
 
        if (ISSET(sc->sc_flags, IWM_FLAG_HW_INITED))
                return 0;
@@ -6436,10 +6450,7 @@
        ifp->if_flags &= ~IFF_OACTIVE;
        ifp->if_flags |= IFF_RUNNING;
 
-       s = splnet();
        ieee80211_begin_scan(&sc->sc_ic, 0);
-       splx(s);
-
        SET(sc->sc_flags, IWM_FLAG_HW_INITED);
 
        return 0;
@@ -6537,7 +6548,6 @@
        struct iwm_softc *sc = ifp->if_softc;
        struct ieee80211com *ic = &sc->sc_ic;
        struct iwm_node *in = (struct iwm_node *)ic->ic_bss;
-       int s;
 
        sc->sc_flags &= ~IWM_FLAG_HW_INITED;
        sc->sc_flags |= IWM_FLAG_STOPPED;
@@ -6547,10 +6557,8 @@
        if (in)
                in->in_phyctxt = NULL;
 
-       s = splnet();
        if (ic->ic_state != IEEE80211_S_INIT)
                ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
-       splx(s);
 
        callout_stop(&sc->sc_calib_to);
        iwm_led_blink_stop(sc);



Home | Main Index | Thread Index | Old Index