From owner-p4-projects@FreeBSD.ORG Sat Feb 16 08:00:44 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 1799C16A41B; Sat, 16 Feb 2008 08:00:44 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B898A16A417 for ; Sat, 16 Feb 2008 08:00:43 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id BCCEC13C455 for ; Sat, 16 Feb 2008 08:00:43 +0000 (UTC) (envelope-from sephe@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id m1G80hZL099482 for ; Sat, 16 Feb 2008 08:00:43 GMT (envelope-from sephe@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id m1G80hVf099479 for perforce@freebsd.org; Sat, 16 Feb 2008 08:00:43 GMT (envelope-from sephe@FreeBSD.org) Date: Sat, 16 Feb 2008 08:00:43 GMT Message-Id: <200802160800.m1G80hVf099479@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sephe@FreeBSD.org using -f From: Sepherosa Ziehau To: Perforce Change Reviews Cc: Subject: PERFORCE change 135480 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 16 Feb 2008 08:00:44 -0000 http://perforce.freebsd.org/chv.cgi?CH=135480 Change 135480 by sephe@sephe_zealot:sam_wifi on 2008/02/16 08:00:42 For MAC rev >= 5, if PHY error interrupt comes then reset the device but leave 802.11 state machine untouched. Affected files ... .. //depot/projects/wifi/sys/dev/bwi/bwimac.c#7 edit .. //depot/projects/wifi/sys/dev/bwi/if_bwi.c#20 edit .. //depot/projects/wifi/sys/dev/bwi/if_bwivar.h#12 edit Differences ... ==== //depot/projects/wifi/sys/dev/bwi/bwimac.c#7 (text+ko) ==== @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.11 2008/01/15 09:01:13 sephe Exp $ + * $DragonFly: src/sys/dev/netif/bwi/bwimac.c,v 1.13 2008/02/15 11:15:38 sephe Exp $ */ #include @@ -1649,6 +1649,8 @@ mac->mac_flags |= BWI_MAC_F_HAS_TXSTATS; DPRINTF(sc, BWI_DBG_MAC | BWI_DBG_ATTACH, "%s\n", "has TX stats"); + } else { + mac->mac_flags |= BWI_MAC_F_PHYE_RESET; } device_printf(sc->sc_dev, "MAC: rev %u\n", rev); ==== //depot/projects/wifi/sys/dev/bwi/if_bwi.c#20 (text+ko) ==== @@ -31,8 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/dev/netif/bwi/if_bwi.c,v 1.18 2008/01/15 09:01:13 sephe Exp $ - * 1.8 is not merged + * $DragonFly: src/sys/dev/netif/bwi/if_bwi.c,v 1.19 2008/02/15 11:15:38 sephe Exp $ */ #include @@ -51,6 +50,7 @@ #include #include #include +#include #include #include @@ -96,6 +96,7 @@ static void bwi_init(void *); static int bwi_ioctl(struct ifnet *, u_long, caddr_t); static void bwi_start(struct ifnet *); +static void bwi_start_locked(struct ifnet *); static void bwi_watchdog(struct ifnet *); static void bwi_scan_start(struct ieee80211com *); static void bwi_set_channel(struct ieee80211com *); @@ -115,7 +116,10 @@ static void bwi_rx_radiotap(struct bwi_softc *, struct mbuf *, struct bwi_rxbuf_hdr *, const void *, int, int); -static void bwi_stop(struct bwi_softc *); +static void bwi_restart(void *, int); +static void bwi_newstate_begin(struct bwi_softc *, enum ieee80211_state); +static void bwi_init_statechg(struct bwi_softc *, int); +static void bwi_stop(struct bwi_softc *, int); static int bwi_newbuf(struct bwi_softc *, int, int); static int bwi_encap(struct bwi_softc *, int, struct mbuf *, struct ieee80211_node *); @@ -348,6 +352,15 @@ BWI_LOCK_INIT(sc); /* + * Initialize taskq and various tasks + */ + sc->sc_tq = taskqueue_create("bwi_taskq", M_NOWAIT | M_ZERO, + taskqueue_thread_enqueue, &sc->sc_tq); + taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", + device_get_nameunit(dev)); + TASK_INIT(&sc->sc_restart_task, 0, bwi_restart, sc); + + /* * Initialize sysctl variables */ sc->sc_fw_version = BWI_FW_VERSION3; @@ -565,7 +578,7 @@ int i; BWI_LOCK(sc); - bwi_stop(sc); + bwi_stop(sc, 1); BWI_UNLOCK(sc); callout_drain(&sc->sc_calib_ch); @@ -576,6 +589,7 @@ bwi_mac_detach(&sc->sc_mac[i]); bwi_dma_free(sc); if_free(ifp); + taskqueue_free(sc->sc_tq); BWI_LOCK_DESTROY(sc); @@ -586,7 +600,7 @@ bwi_suspend(struct bwi_softc *sc) { BWI_LOCK(sc); - bwi_stop(sc); + bwi_stop(sc, 1); BWI_UNLOCK(sc); } @@ -606,7 +620,7 @@ bwi_shutdown(struct bwi_softc *sc) { BWI_LOCK(sc); - bwi_stop(sc); + bwi_stop(sc, 1); BWI_UNLOCK(sc); return 0; } @@ -1166,7 +1180,12 @@ static void bwi_init(void *xsc) { - struct bwi_softc *sc = xsc; + bwi_init_statechg(xsc, 1); +} + +static void +bwi_init_statechg(struct bwi_softc *sc, int statechg) +{ struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = ic->ic_ifp; struct bwi_mac *mac; @@ -1174,7 +1193,7 @@ BWI_LOCK(sc); - bwi_stop(sc); + bwi_stop(sc, statechg); bwi_bbp_power_on(sc, BWI_CLOCK_MODE_FAST); @@ -1233,15 +1252,24 @@ ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) - ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); + if (statechg) { + if (ic->ic_opmode != IEEE80211_M_MONITOR) { + if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) + ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); + } else { + ieee80211_new_state(ic, IEEE80211_S_RUN, -1); + } } else { - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); + /* XXX */ + if (ic->ic_state != IEEE80211_S_INIT) + bwi_set_channel(ic); + ieee80211_new_state(ic, ic->ic_state, -1); } back: if (error) - bwi_stop(sc); + bwi_stop(sc, 1); + else + bwi_start_locked(ifp); BWI_UNLOCK(sc); } @@ -1285,7 +1313,7 @@ bwi_init(sc); } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) - bwi_stop(sc); + bwi_stop(sc, 1); } break; default: @@ -1308,6 +1336,16 @@ bwi_start(struct ifnet *ifp) { struct bwi_softc *sc = ifp->if_softc; + + BWI_LOCK(sc); + bwi_start_locked(ifp); + BWI_UNLOCK(sc); +} + +static void +bwi_start_locked(struct ifnet *ifp) +{ + struct bwi_softc *sc = ifp->if_softc; struct ieee80211com *ic = &sc->sc_ic; struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; struct ieee80211_frame *wh; @@ -1317,12 +1355,9 @@ struct mbuf *m; int trans, idx; - BWI_LOCK(sc); if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) || - (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { - BWI_UNLOCK(sc); + (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return; - } trans = 0; idx = tbd->tbd_idx; @@ -1404,7 +1439,6 @@ if (trans) ifp->if_timer = 5; - BWI_UNLOCK(sc); } static void @@ -1416,13 +1450,13 @@ if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) { if_printf(ifp, "watchdog timeout\n"); ifp->if_oerrors++; - /* TODO */ + taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task); } BWI_UNLOCK(sc); } static void -bwi_stop(struct bwi_softc *sc) +bwi_stop(struct bwi_softc *sc, int statechg) { struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = ic->ic_ifp; @@ -1432,7 +1466,10 @@ BWI_ASSERT_LOCKED(sc); sc->sc_flags |= BWI_F_STOP; - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); + if (statechg) + ieee80211_new_state(ic, IEEE80211_S_INIT, -1); + else + bwi_newstate_begin(sc, IEEE80211_S_INIT); if (ifp->if_drv_flags & IFF_DRV_RUNNING) { KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, @@ -1473,6 +1510,7 @@ bwi_intr(void *xsc) { struct bwi_softc *sc = xsc; + struct bwi_mac *mac; struct ifnet *ifp = sc->sc_ic.ic_ifp; uint32_t intr_status; uint32_t txrx_intr_status[BWI_TXRX_NRING]; @@ -1502,6 +1540,10 @@ return; } + KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, + ("current regwin type %d", sc->sc_cur_regwin->rw_type)); + mac = (struct bwi_mac *)sc->sc_cur_regwin; + txrx_error = 0; DPRINTF(sc, BWI_DBG_INTR, "%s\n", "TX/RX intr"); for (i = 0; i < BWI_TXRX_NRING; ++i) { @@ -1537,18 +1579,21 @@ /* Disable all interrupts */ bwi_disable_intrs(sc, BWI_ALL_INTRS); - if (intr_status & BWI_INTR_PHY_TXERR) - if_printf(ifp, "intr PHY TX error\n"); + if (intr_status & BWI_INTR_PHY_TXERR) { + if (mac->mac_flags & BWI_MAC_F_PHYE_RESET) { + if_printf(ifp, "intr PHY TX error\n"); + taskqueue_enqueue(sc->sc_tq, &sc->sc_restart_task); + BWI_UNLOCK(sc); + return; + } + } if (txrx_error) { /* TODO: reset device */ } - if (intr_status & BWI_INTR_TBTT) { - KASSERT(sc->sc_cur_regwin->rw_type == BWI_REGWIN_T_MAC, - ("current regwin type %d", sc->sc_cur_regwin->rw_type)); - bwi_mac_config_ps((struct bwi_mac *)sc->sc_cur_regwin); - } + if (intr_status & BWI_INTR_TBTT) + bwi_mac_config_ps(mac); if (intr_status & BWI_INTR_EO_ATIM) if_printf(ifp, "EO_ATIM\n"); @@ -1633,6 +1678,20 @@ { } +static void +bwi_newstate_begin(struct bwi_softc *sc, enum ieee80211_state nstate) +{ + BWI_ASSERT_LOCKED(sc); + + callout_stop(&sc->sc_calib_ch); + callout_stop(&sc->sc_amrr_ch); + + bwi_led_newstate(sc, nstate); + + if (nstate == IEEE80211_S_INIT) + sc->sc_txpwrcb_type = BWI_TXPWR_INIT; +} + static int bwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) { @@ -1644,10 +1703,7 @@ BWI_LOCK(sc); - callout_stop(&sc->sc_calib_ch); - callout_stop(&sc->sc_amrr_ch); - - bwi_led_newstate(sc, nstate); + bwi_newstate_begin(sc, nstate); if (nstate == IEEE80211_S_INIT) goto back; @@ -4041,3 +4097,12 @@ } return txtime; } + +static void +bwi_restart(void *xsc, int pending) +{ + struct bwi_softc *sc = xsc; + + if_printf(sc->sc_ifp, "%s begin\n", __func__); + bwi_init_statechg(xsc, 0); +} ==== //depot/projects/wifi/sys/dev/bwi/if_bwivar.h#12 (text+ko) ==== @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/dev/netif/bwi/if_bwivar.h,v 1.13 2008/01/15 09:01:13 sephe Exp $ + * $DragonFly: src/sys/dev/netif/bwi/if_bwivar.h,v 1.14 2008/02/15 11:15:38 sephe Exp $ * 1.9 is not merged */ @@ -476,6 +476,7 @@ #define BWI_MAC_F_ENABLED 0x10 #define BWI_MAC_F_LOCKED 0x20 /* for debug */ #define BWI_MAC_F_TPCTL_ERROR 0x40 +#define BWI_MAC_F_PHYE_RESET 0x80 #define BWI_CREATE_MAC(mac, sc, id, rev) \ do { \ @@ -608,6 +609,9 @@ struct bwi_rx_radiotap_hdr sc_rx_th; int sc_rx_th_len; + struct taskqueue *sc_tq; + struct task sc_restart_task; + int (*sc_newstate) (struct ieee80211com *, enum ieee80211_state, int);