----- Original Message ---- > From: Hans Petter Selasky <hselasky_at_c2i.net> > To: freebsd-current_at_freebsd.org > Cc: Andrew Thompson <thompsa_at_freebsd.org>; Sam Leffler <sam_at_freebsd.org>; >PseudoCylon <moonlightakkiy_at_yahoo.ca>; freebsd-usb_at_freebsd.org > Sent: Mon, July 12, 2010 2:01:11 PM > Subject: Re: [panic] Race in IEEE802.11 layer towards device drivers > > Hi Andrew, > > Your patch appears to be working. Can you fix this issue in the other WLAN > drivers aswell? Then send an e-mail to request testing? I had a go at it here: > > http://p4web.freebsd.org/_at__at_180844?ac=10 > Can this patch be included into testing? patch to P4 USB rev. 14 if_run.c If not, at least please delete an extra semicolon at the end of line 3191 (must be an merge bug). I missed it since it wans't in diff/patch. AK summary of changes * fixes bugs in rev 209144 a shared key was written properly only on first time init, but not subsequent init. Make sure the key is written all the time. * stop checking 'pending' in run_cmdq_cb(). When loop 'pending' times, new tasks enqueued while looping won't be executed because 'pending' passed from taskqueue function won't be incremented. -- patch begin -- diff --git a/dev/usb/wlan/if_run.c b/dev/usb/wlan/if_run.c index 7a3952c..12b45ec 100644 --- a/dev/usb/wlan/if_run.c +++ b/dev/usb/wlan/if_run.c _at__at_ -830,9 +830,6 _at__at_ run_vap_create(struct ieee80211com *ic, if(sc->rvp_cnt++ == 0) ic->ic_opmode = opmode; -if(opmode == IEEE80211_M_HOSTAP) -sc->cmdq_run = RUN_CMDQ_GO; - DPRINTF("rvp_id=%d bmap=%x rvp_cnt=%d\n", rvp->rvp_id, sc->rvp_bmap, sc->rvp_cnt); _at__at_ -891,15 +888,16 _at__at_ run_cmdq_cb(void *arg, int pending) /* call cmdq[].func locked */ RUN_LOCK(sc); -for(i = sc->cmdq_exec; sc->cmdq[i].func && pending; - i = sc->cmdq_exec, pending--){ +for (i = sc->cmdq_exec; sc->cmdq[i].func; i = sc->cmdq_exec) { DPRINTFN(6, "cmdq_exec=%d pending=%d\n", i, pending); -if(sc->cmdq_run == RUN_CMDQ_GO){ +if (sc->cmdq_run == RUN_CMDQ_GO || + (sc->cmdq_key_set == RUN_CMDQ_GO && + sc->cmdq[i].func == run_key_set_cb)) { /* * If arg0 is NULL, callback func needs more * than one arg. So, pass ptr to cmdq struct. */ -if(sc->cmdq[i].arg0) +if (sc->cmdq[i].arg0) sc->cmdq[i].func(sc->cmdq[i].arg0); else sc->cmdq[i].func(&sc->cmdq[i]); _at__at_ -1771,6 +1769,19 _at__at_ run_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) case IEEE80211_S_INIT: restart_ratectl = 1; +/* + * When hostapd has set a key, don't clear it. + * But, when the device is being brought down, clear it. + */ +if (sc->cmdq_key_set != RUN_CMDQ_GO || + ostate == IEEE80211_S_RUN) { +/* clear shared key table */ +run_set_region_4(sc, + RT2860_SKEY(rvp->rvp_id, 0), 0, 4 * 32); +/* clear shared key mode */ +run_set_region_4(sc, RT2860_SKEY_MODE_0_7, 0, 4); +} + if (ostate != IEEE80211_S_RUN) break; _at__at_ -2100,13 +2111,10 _at__at_ run_key_set(struct ieee80211vap *vap, struct ieee80211_key *k, * To make sure key will be set when hostapd * calls iv_key_set() before if_init(). */ -if(vap->iv_opmode == IEEE80211_M_HOSTAP){ -RUN_LOCK(sc); +if (vap->iv_opmode == IEEE80211_M_HOSTAP) sc->cmdq_key_set = RUN_CMDQ_GO; -RUN_UNLOCK(sc); -} -return(1); +return (1); } /* _at__at_ -3188,7 +3196,7 _at__at_ run_sendprot(struct run_softc *sc, ackrate = ieee80211_ack_rate(ic->ic_rt, rate); isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; -dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort); +dur = ieee80211_compute_duration(ic->ic_rt, pktlen, rate, isshort) + ieee80211_ack_duration(ic->ic_rt, rate, isshort); wflags = RT2860_TX_FRAG; _at__at_ -4693,14 +4701,6 _at__at_ run_init_locked(struct run_softc *sc) /* clear WCID attribute table */ run_set_region_4(sc, RT2860_WCID_ATTR(0), 0, 8 * 32); -/* hostapd sets a key before init. So, don't clear it. */ -if(sc->cmdq_key_set != RUN_CMDQ_GO){ -/* clear shared key table */ -run_set_region_4(sc, RT2860_SKEY(0, 0), 0, 8 * 32); -/* clear shared key mode */ -run_set_region_4(sc, RT2860_SKEY_MODE_0_7, 0, 4); -} - run_read(sc, RT2860_US_CYC_CNT, &tmp); tmp = (tmp & ~0xff) | 0x1e; run_write(sc, RT2860_US_CYC_CNT, tmp); _at__at_ -4807,7 +4807,7 _at__at_ run_stop(void *arg) ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); sc->ratectl_run = RUN_RATECTL_OFF; -sc->cmdq_run = sc->cmdq_key_set; +sc->cmdq_run = RUN_CMDQ_ABORT; RUN_UNLOCK(sc); -- end patch --Received on Wed Jul 14 2010 - 10:31:30 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:05 UTC