From owner-svn-src-all@FreeBSD.ORG Thu May 22 14:56:34 2014 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id A52CAAA4; Thu, 22 May 2014 14:56:34 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 8605129F1; Thu, 22 May 2014 14:56:34 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.8/8.14.8) with ESMTP id s4MEuYuM095775; Thu, 22 May 2014 14:56:34 GMT (envelope-from trasz@svn.freebsd.org) Received: (from trasz@localhost) by svn.freebsd.org (8.14.8/8.14.8/Submit) id s4MEuYkb095774; Thu, 22 May 2014 14:56:34 GMT (envelope-from trasz@svn.freebsd.org) Message-Id: <201405221456.s4MEuYkb095774@svn.freebsd.org> From: Edward Tomasz Napierala Date: Thu, 22 May 2014 14:56:34 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r266544 - head/sys/dev/iwn X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 May 2014 14:56:34 -0000 Author: trasz Date: Thu May 22 14:56:34 2014 New Revision: 266544 URL: http://svnweb.freebsd.org/changeset/base/266544 Log: Make iwn(4) able to get itself back into working condition after "fatal firmware error" happens. Previously it was neccessary to reset it manually, using "/etc/rc.d/netif restart". Approved by: adrian@ MFC after: 1 month Sponsored by: The FreeBSD Foundation Modified: head/sys/dev/iwn/if_iwn.c Modified: head/sys/dev/iwn/if_iwn.c ============================================================================== --- head/sys/dev/iwn/if_iwn.c Thu May 22 12:30:56 2014 (r266543) +++ head/sys/dev/iwn/if_iwn.c Thu May 22 14:56:34 2014 (r266544) @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -342,6 +343,7 @@ static void iwn_set_channel(struct ieee8 static void iwn_scan_curchan(struct ieee80211_scan_state *, unsigned long); static void iwn_scan_mindwell(struct ieee80211_scan_state *); static void iwn_hw_reset(void *, int); +static void iwn_reinit_thread(void *); #ifdef IWN_DEBUG static char *iwn_get_csr_string(int); static void iwn_debug_register(struct iwn_softc *); @@ -1197,6 +1199,8 @@ iwn4965_attach(struct iwn_softc *sc, uin /* Enable normal btcoex */ sc->sc_flags |= IWN_FLAG_BTCOEX; + kthread_add(iwn_reinit_thread, sc, NULL, NULL, 0, 0, "iwn_reinit"); + DPRINTF(sc, IWN_DEBUG_TRACE, "%s: end\n",__func__); return 0; @@ -3884,6 +3888,52 @@ iwn_fatal_intr(struct iwn_softc *sc) } static void +iwn_reinit_thread(void *arg) +{ + struct iwn_softc *sc = arg; + int error; + + mtx_lock(&sc->sc_mtx); + for (;;) { + struct ifnet *ifp; + struct ieee80211com *ic; + struct ieee80211vap *vap; + + msleep(&sc->fwname, &sc->sc_mtx, PCATCH, "iwn_reinit", 0); + + ifp = sc->sc_ifp; + ic = ifp->if_l2com; + vap = TAILQ_FIRST(&ic->ic_vaps); + + if (vap == NULL) { + printf("%s: null vap\n", __func__); + continue; + } + + device_printf(sc->sc_dev, "%s: controller panicked; " + "resetting; iv_state = %d...\n", __func__, vap->iv_state); + mtx_unlock(&sc->sc_mtx); + iwn_stop(sc); + iwn_init(sc); + iwn_start(sc->sc_ifp); + if (vap->iv_state >= IEEE80211_S_AUTH && + (error = iwn_auth(sc, vap)) != 0) { + device_printf(sc->sc_dev, + "%s: could not move to auth state\n", __func__); + } + if (vap->iv_state >= IEEE80211_S_RUN && + (error = iwn_run(sc, vap)) != 0) { + device_printf(sc->sc_dev, + "%s: could not move to run state\n", __func__); + } + mtx_lock(&sc->sc_mtx); + } + mtx_unlock(&sc->sc_mtx); + + kthread_exit(); +} + +static void iwn_intr(void *arg) { struct iwn_softc *sc = arg; @@ -3944,8 +3994,10 @@ iwn_intr(void *arg) #endif /* Dump firmware error log and stop. */ iwn_fatal_intr(sc); - ifp->if_flags &= ~IFF_UP; - iwn_stop_locked(sc); + + device_printf(sc->sc_dev, "%s: reinit; %p\n", + __func__, &sc->fwname); + wakeup(&sc->fwname); goto done; } if ((r1 & (IWN_INT_FH_RX | IWN_INT_SW_RX | IWN_INT_RX_PERIODIC)) ||