| 1 | --- a/net80211/ieee80211_proto.c |
| 2 | +++ b/net80211/ieee80211_proto.c |
| 3 | @@ -1415,7 +1415,8 @@ __ieee80211_newstate(struct ieee80211vap |
| 4 | vap->iv_state = nstate; /* state transition */ |
| 5 | del_timer(&vap->iv_mgtsend); |
| 6 | if ((vap->iv_opmode != IEEE80211_M_HOSTAP) && |
| 7 | - (ostate != IEEE80211_S_SCAN)) |
| 8 | + (ostate != IEEE80211_S_SCAN) && |
| 9 | + !(vap->iv_flags_ext & IEEE80211_FEXT_SCAN_PENDING)) |
| 10 | ieee80211_cancel_scan(vap); /* background scan */ |
| 11 | ni = vap->iv_bss; /* NB: no reference held */ |
| 12 | switch (nstate) { |
| 13 | @@ -1457,7 +1458,8 @@ __ieee80211_newstate(struct ieee80211vap |
| 14 | } |
| 15 | goto reset; |
| 16 | case IEEE80211_S_SCAN: |
| 17 | - ieee80211_cancel_scan(vap); |
| 18 | + if (!(vap->iv_flags_ext & IEEE80211_FEXT_SCAN_PENDING)) |
| 19 | + ieee80211_cancel_scan(vap); |
| 20 | goto reset; |
| 21 | reset: |
| 22 | ieee80211_reset_bss(vap); |
| 23 | @@ -1995,7 +1997,9 @@ ieee80211_newstate(struct ieee80211vap * |
| 24 | } |
| 25 | } |
| 26 | } |
| 27 | - } else if (dstate == IEEE80211_S_SCAN) { |
| 28 | + } else if ((dstate == IEEE80211_S_SCAN) || |
| 29 | + (dstate == IEEE80211_S_AUTH) || |
| 30 | + (dstate == IEEE80211_S_ASSOC)) { |
| 31 | /* Force to scan pending... someone is scanning */ |
| 32 | vap->iv_flags_ext |= IEEE80211_FEXT_SCAN_PENDING; |
| 33 | __ieee80211_newstate(vap, IEEE80211_S_INIT, arg); |
| 34 | --- a/net80211/ieee80211_output.c |
| 35 | +++ b/net80211/ieee80211_output.c |
| 36 | @@ -238,7 +238,9 @@ ieee80211_hardstart(struct sk_buff *skb, |
| 37 | } |
| 38 | |
| 39 | /* Cancel any running BG scan */ |
| 40 | - if (!(ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && (vap->iv_state == IEEE80211_S_RUN)) |
| 41 | + if (!(ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN_THR) && |
| 42 | + (vap->iv_state == IEEE80211_S_RUN) && |
| 43 | + (ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN)) |
| 44 | ieee80211_cancel_scan(vap); |
| 45 | |
| 46 | /* |
| 47 | --- a/net80211/ieee80211_wireless.c |
| 48 | +++ b/net80211/ieee80211_wireless.c |
| 49 | @@ -2728,9 +2728,9 @@ ieee80211_ioctl_setparam(struct net_devi |
| 50 | return -EINVAL; |
| 51 | vap->iv_flags |= IEEE80211_F_BGSCAN; |
| 52 | } else { |
| 53 | - /* XXX racey? */ |
| 54 | + if (ic->ic_flags_ext & IEEE80211_FEXT_BGSCAN) |
| 55 | + ieee80211_cancel_scan(vap); /* anything current */ |
| 56 | vap->iv_flags &= ~IEEE80211_F_BGSCAN; |
| 57 | - ieee80211_cancel_scan(vap); /* anything current */ |
| 58 | } |
| 59 | break; |
| 60 | case IEEE80211_PARAM_BGSCAN_IDLE: |
| 61 | |