From owner-p4-projects@FreeBSD.ORG Wed Feb 11 21:40:30 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id EACCA1065673; Wed, 11 Feb 2009 21:40:29 +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 A82401065670 for ; Wed, 11 Feb 2009 21:40:29 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 94A228FC2D for ; Wed, 11 Feb 2009 21:40:29 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n1BLeTDG008425 for ; Wed, 11 Feb 2009 21:40:29 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n1BLeTZF008423 for perforce@freebsd.org; Wed, 11 Feb 2009 21:40:29 GMT (envelope-from hselasky@FreeBSD.org) Date: Wed, 11 Feb 2009 21:40:29 GMT Message-Id: <200902112140.n1BLeTZF008423@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 157570 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: Wed, 11 Feb 2009 21:40:31 -0000 http://perforce.freebsd.org/chv.cgi?CH=157570 Change 157570 by hselasky@hselasky_laptop001 on 2009/02/11 21:39:58 USB WLAN patches. - try to handle more detach races with the network stack - next state and argument must be atomically read before passing to iv_nextstate callback - increase control request timeout - make sure INIT state is handled correctly USB wise - revert changes to "ieee80211_proto.c" Affected files ... .. //depot/projects/usb/src/sys/dev/usb2/wlan/if_rum2.c#38 edit .. //depot/projects/usb/src/sys/dev/usb2/wlan/if_ural2.c#37 edit .. //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2.c#38 edit .. //depot/projects/usb/src/sys/net80211/ieee80211_proto.c#13 edit Differences ... ==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_rum2.c#38 (text+ko) ==== @@ -125,7 +125,7 @@ static usb2_proc_callback_t rum_stop_task; static usb2_proc_callback_t rum_flush_task; -static void rum_do_request(struct rum_softc *sc, +static usb2_error_t rum_do_request(struct rum_softc *sc, struct usb2_device_request *req, void *data); static struct ieee80211vap *rum_vap_create(struct ieee80211com *, const char name[IFNAMSIZ], int unit, int opmode, @@ -154,8 +154,8 @@ static uint32_t rum_read(struct rum_softc *, uint16_t); static void rum_read_multi(struct rum_softc *, uint16_t, void *, int); -static void rum_write(struct rum_softc *, uint16_t, uint32_t); -static void rum_write_multi(struct rum_softc *, uint16_t, void *, +static usb2_error_t rum_write(struct rum_softc *, uint16_t, uint32_t); +static usb2_error_t rum_write_multi(struct rum_softc *, uint16_t, void *, size_t); static void rum_bbp_write(struct rum_softc *, uint8_t, uint8_t); static uint8_t rum_bbp_read(struct rum_softc *, uint8_t); @@ -178,7 +178,7 @@ static void rum_read_eeprom(struct rum_softc *); static int rum_bbp_init(struct rum_softc *); static void rum_init(void *); -static int rum_load_microcode(struct rum_softc *, const uint8_t *, +static void rum_load_microcode(struct rum_softc *, const uint8_t *, size_t); static int rum_prepare_beacon(struct rum_softc *, struct ieee80211vap *); @@ -444,7 +444,6 @@ struct ifnet *ifp; struct ieee80211com *ic; unsigned int ntries; - int error; uint32_t tmp; uint8_t bands; @@ -466,11 +465,12 @@ device_printf(sc->sc_dev, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n", tmp, rum_get_rf(sc->rf_rev)); - error = rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode)); - if (error != 0) { - device_printf(sc->sc_dev, "could not load 8051 microcode\n"); + rum_load_microcode(sc, rt2573_ucode, sizeof(rt2573_ucode)); + + /* XXX WLAN race --hps */ + if (usb2_proc_is_gone(&sc->sc_tq)) return; - } + RUM_UNLOCK(sc); ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); @@ -578,20 +578,21 @@ return (0); } -static void +static usb2_error_t rum_do_request(struct rum_softc *sc, struct usb2_device_request *req, void *data) { usb2_error_t err; err = usb2_do_request_proc(sc->sc_udev, &sc->sc_tq, - req, data, 0, NULL, 250 /* ms */); + req, data, 0, NULL, 1000 /* ms */); if (err) { - DPRINTFN(1, "Control request failed! (ignored)\n"); + DPRINTFN(1, "Control request failed, " + "%s! (ignored)\n", usb2_errstr(err)); rum_pause(sc, hz / 100); } - return; + return (err); } static struct ieee80211vap * @@ -736,21 +737,21 @@ struct rum_vap *rvp = RUM_VAP(vap); const struct ieee80211_txparam *tp; enum ieee80211_state ostate; + enum ieee80211_state nstate; struct ieee80211_node *ni; + int arg; uint32_t tmp; ostate = vap->iv_state; + nstate = sc->sc_state; + arg = sc->sc_arg; /* callout it stopped */ usb2_callout_stop(&rvp->amrr_ch); - switch (sc->sc_state) { + switch (nstate) { case IEEE80211_S_INIT: if (ostate == IEEE80211_S_RUN) { - /* - * BUG: this code is not executed like it - * should --hps - */ /* abort TSF synchronization */ tmp = rum_read(sc, RT2573_TXRX_CSR9); rum_write(sc, RT2573_TXRX_CSR9, tmp & ~0x00ffffff); @@ -785,11 +786,17 @@ break; } + /* sanity checks */ + if (nstate == IEEE80211_S_INIT) + return; + if (nstate != sc->sc_state) + return; + RUM_UNLOCK(sc); IEEE80211_LOCK(ic); - rvp->newstate(vap, sc->sc_state, sc->sc_arg); + rvp->newstate(vap, nstate, arg); if (vap->iv_newstate_cb != NULL) - vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); + vap->iv_newstate_cb(vap, nstate, arg); IEEE80211_UNLOCK(ic); RUM_LOCK(sc); } @@ -809,18 +816,16 @@ /* do it in a process context */ sc->sc_state = nstate; sc->sc_arg = arg; + rum_queue_command(sc, rum_task, + &sc->sc_task[0].hdr, + &sc->sc_task[1].hdr); RUM_UNLOCK(sc); if (nstate == IEEE80211_S_INIT) { rvp->newstate(vap, nstate, arg); return 0; - } else { - RUM_LOCK(sc); - rum_queue_command(sc, rum_task, &sc->sc_task[0].hdr, - &sc->sc_task[1].hdr); - RUM_UNLOCK(sc); - return EINPROGRESS; } + return (EINPROGRESS); } static void @@ -1084,8 +1089,6 @@ } } -#define RUM_TX_TIMEOUT 5000 - static int rum_sendprot(struct rum_softc *sc, const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) @@ -1468,15 +1471,15 @@ rum_do_request(sc, &req, buf); } -static void +static usb2_error_t rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val) { uint32_t tmp = htole32(val); - rum_write_multi(sc, reg, &tmp, sizeof tmp); + return (rum_write_multi(sc, reg, &tmp, sizeof tmp)); } -static void +static usb2_error_t rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len) { struct usb2_device_request req; @@ -1487,7 +1490,7 @@ USETW(req.wIndex, reg); USETW(req.wLength, len); - rum_do_request(sc, &req, buf); + return (rum_do_request(sc, &req, buf)); } static void @@ -1496,6 +1499,8 @@ uint32_t tmp; int ntries; + DPRINTFN(2, "reg=0x%08x\n", reg); + for (ntries = 0; ntries != 100; ntries++) { if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY)) break; @@ -1517,6 +1522,8 @@ uint32_t val; int ntries; + DPRINTFN(2, "reg=0x%08x\n", reg); + for (ntries = 0; ntries != 100; ntries++) { if (!(rum_read(sc, RT2573_PHY_CSR3) & RT2573_BBP_BUSY)) break; @@ -2088,6 +2095,8 @@ rum_write(sc, RT2573_TXRX_CSR0, tmp); ifp->if_drv_flags |= IFF_DRV_RUNNING; + + usb2_transfer_set_stall(sc->sc_xfer[RUM_BULK_WR]); usb2_transfer_start(sc->sc_xfer[RUM_BULK_RD]); return; @@ -2145,20 +2154,22 @@ rum_write(sc, RT2573_MAC_CSR1, 0); } -static int +static void rum_load_microcode(struct rum_softc *sc, const uint8_t *ucode, size_t size) { struct usb2_device_request req; uint16_t reg = RT2573_MCU_CODE_BASE; - - /* - * TODO: If the firmware is already loaded, - * then we need to return from here! - */ + usb2_error_t err; /* copy firmware image into NIC */ - for (; size >= 4; reg += 4, ucode += 4, size -= 4) - rum_write(sc, reg, UGETDW(ucode)); + for (; size >= 4; reg += 4, ucode += 4, size -= 4) { + err = rum_write(sc, reg, UGETDW(ucode)); + if (err) { + /* firmware already loaded ? */ + device_printf(sc->sc_dev, "Firmware load failed.\n"); + break; + } + } req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = RT2573_MCU_CNTL; @@ -2167,7 +2178,9 @@ USETW(req.wLength, 0); rum_do_request(sc, &req, NULL); - return (0); + + /* give the chip some time to boot */ + rum_pause(sc, hz / 8); } static int @@ -2359,10 +2372,9 @@ RUM_LOCK(sc); /* do it in a process context */ sc->sc_scan_action = RUM_SET_CHANNEL; + sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); rum_queue_command(sc, rum_scantask, &sc->sc_scantask[0].hdr, &sc->sc_scantask[1].hdr); - - sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); RUM_UNLOCK(sc); } ==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_ural2.c#37 (text+ko) ==== @@ -454,6 +454,11 @@ /* retrieve MAC address and various other things from EEPROM */ ural_read_eeprom(sc); + + /* XXX WLAN race --hps */ + if (usb2_proc_is_gone(&sc->sc_tq)) + return; + RAL_UNLOCK(sc); device_printf(sc->sc_dev, "MAC/BBP RT2570 (rev 0x%02x), RF %s\n", @@ -571,7 +576,7 @@ usb2_error_t err; err = usb2_do_request_proc(sc->sc_udev, &sc->sc_tq, - req, data, 0, NULL, 250 /* ms */); + req, data, 0, NULL, 1000 /* ms */); if (err) { DPRINTFN(1, "Control request failed! (ignored)\n"); @@ -721,21 +726,21 @@ struct ural_vap *uvp = URAL_VAP(vap); const struct ieee80211_txparam *tp; enum ieee80211_state ostate; + enum ieee80211_state nstate; struct ieee80211_node *ni; struct mbuf *m; + int arg; ostate = vap->iv_state; + nstate = sc->sc_state; + arg = sc->sc_arg; /* callout is stopped */ usb2_callout_stop(&uvp->amrr_ch); - switch (sc->sc_state) { + switch (nstate) { case IEEE80211_S_INIT: if (ostate == IEEE80211_S_RUN) { - /* - * BUG: this code is not executed like it - * should --hps - */ /* abort TSF synchronization */ ural_write(sc, RAL_TXRX_CSR19, 0); @@ -788,11 +793,17 @@ break; } + /* sanity checks */ + if (nstate == IEEE80211_S_INIT) + return; + if (nstate != sc->sc_state) + return; + RAL_UNLOCK(sc); IEEE80211_LOCK(ic); - uvp->newstate(vap, sc->sc_state, sc->sc_arg); + uvp->newstate(vap, nstate, arg); if (vap->iv_newstate_cb != NULL) - vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); + vap->iv_newstate_cb(vap, nstate, arg); IEEE80211_UNLOCK(ic); RAL_LOCK(sc); } @@ -842,21 +853,18 @@ /* do it in a process context */ sc->sc_state = nstate; sc->sc_arg = arg; + ural_queue_command(sc, ural_task, + &sc->sc_task[0].hdr, + &sc->sc_task[1].hdr); RAL_UNLOCK(sc); if (nstate == IEEE80211_S_INIT) { uvp->newstate(vap, nstate, arg); return 0; - } else { - RAL_LOCK(sc); - ural_queue_command(sc, ural_task, &sc->sc_task[0].hdr, - &sc->sc_task[1].hdr); - RAL_UNLOCK(sc); - return EINPROGRESS; } + return (EINPROGRESS); } - static void ural_bulk_write_callback(struct usb2_xfer *xfer) { @@ -1726,7 +1734,7 @@ struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; uint8_t power, tmp; - u_int i, chan; + unsigned int i, chan; chan = ieee80211_chan2ieee(ic, c); if (chan == 0 || chan == IEEE80211_CHAN_ANY) @@ -2215,6 +2223,7 @@ ural_write(sc, RAL_TXRX_CSR2, tmp); ifp->if_drv_flags |= IFF_DRV_RUNNING; + usb2_transfer_set_stall(sc->sc_xfer[URAL_BULK_WR]); usb2_transfer_start(sc->sc_xfer[URAL_BULK_RD]); return; ==== //depot/projects/usb/src/sys/dev/usb2/wlan/if_zyd2.c#38 (text+ko) ==== @@ -105,7 +105,7 @@ const uint8_t mac[IEEE80211_ADDR_LEN]); static int zyd_newstate(struct ieee80211vap *, enum ieee80211_state, int); static int zyd_cmd(struct zyd_softc *, uint16_t, const void *, int, - void *, int, u_int); + void *, int, unsigned int); static int zyd_read16(struct zyd_softc *, uint16_t, uint16_t *); static int zyd_read32(struct zyd_softc *, uint16_t, uint32_t *); static int zyd_write16(struct zyd_softc *, uint16_t, uint16_t); @@ -371,6 +371,10 @@ return; } + /* XXX WLAN race --hps */ + if (usb2_proc_is_gone(&sc->sc_tq)) + return; + ZYD_UNLOCK(sc); ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); @@ -612,10 +616,15 @@ struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_node *ni = vap->iv_bss; + enum ieee80211_state nstate; struct zyd_vap *zvp = ZYD_VAP(vap); + int arg; int error; - switch (sc->sc_state) { + nstate = sc->sc_state; + arg = sc->sc_arg; + + switch (nstate) { case IEEE80211_S_AUTH: zyd_set_chan(sc, ic->ic_curchan); break; @@ -638,11 +647,17 @@ break; } fail: + /* sanity checks */ + if (nstate == IEEE80211_S_INIT) + return; + if (nstate != sc->sc_state) + return; + ZYD_UNLOCK(sc); IEEE80211_LOCK(ic); - zvp->newstate(vap, sc->sc_state, sc->sc_arg); + zvp->newstate(vap, nstate, arg); if (vap->iv_newstate_cb != NULL) - vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); + vap->iv_newstate_cb(vap, nstate, arg); IEEE80211_UNLOCK(ic); ZYD_LOCK(sc); } @@ -662,18 +677,16 @@ /* do it in a process context */ sc->sc_state = nstate; sc->sc_arg = arg; + zyd_queue_command(sc, zyd_task, + &sc->sc_task[0].hdr, + &sc->sc_task[1].hdr); ZYD_UNLOCK(sc); if (nstate == IEEE80211_S_INIT) { zvp->newstate(vap, nstate, arg); return (0); - } else { - ZYD_LOCK(sc); - zyd_queue_command(sc, zyd_task, &sc->sc_task[0].hdr, - &sc->sc_task[1].hdr); - ZYD_UNLOCK(sc); - return (EINPROGRESS); } + return (EINPROGRESS); } /* @@ -829,7 +842,7 @@ static int zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen, - void *odata, int olen, u_int flags) + void *odata, int olen, unsigned int flags) { struct zyd_cmd cmd; struct zyd_rq rq; @@ -1279,7 +1292,7 @@ struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; struct zyd_phy_pair r[] = ZYD_AL2230_PHY_BANDEDGE6; - u_int chan = ieee80211_chan2ieee(ic, c); + unsigned int chan = ieee80211_chan2ieee(ic, c); if (chan == 1 || chan == 11) r[0].val = 0x12; @@ -2104,7 +2117,7 @@ struct ieee80211com *ic = ifp->if_l2com; struct zyd_rf *rf = &sc->sc_rf; uint32_t tmp; - u_int chan; + unsigned int chan; chan = ieee80211_chan2ieee(ic, c); if (chan == 0 || chan == IEEE80211_CHAN_ANY) { @@ -2885,6 +2898,7 @@ zyd_write32_m(sc, ZYD_CR_INTERRUPT, ZYD_HWINT_MASK); ifp->if_drv_flags |= IFF_DRV_RUNNING; + usb2_transfer_set_stall(sc->sc_xfer[ZYD_BULK_WR]); usb2_transfer_start(sc->sc_xfer[ZYD_BULK_RD]); usb2_transfer_start(sc->sc_xfer[ZYD_INTR_RD]); ==== //depot/projects/usb/src/sys/net80211/ieee80211_proto.c#13 (text+ko) ==== @@ -154,8 +154,6 @@ ieee80211_wds_detach(ic); ieee80211_adhoc_detach(ic); ieee80211_sta_detach(ic); - - taskqueue_drain(taskqueue_thread, &ic->ic_parent_task); } static void