Index: head/sys/net80211/ieee80211_freebsd.h =================================================================== --- head/sys/net80211/ieee80211_freebsd.h +++ head/sys/net80211/ieee80211_freebsd.h @@ -254,9 +254,9 @@ #define ticks_to_msecs(t) TICKS_2_MSEC(t) #define ticks_to_secs(t) ((t) / hz) -#define ieee80211_time_after(a,b) ((long)(b) - (long)(a) < 0) +#define ieee80211_time_after(a,b) ((int)(b) - (int)(a) < 0) #define ieee80211_time_before(a,b) ieee80211_time_after(b,a) -#define ieee80211_time_after_eq(a,b) ((long)(a) - (long)(b) >= 0) +#define ieee80211_time_after_eq(a,b) ((int)(a) - (int)(b) >= 0) #define ieee80211_time_before_eq(a,b) ieee80211_time_after_eq(b,a) struct mbuf *ieee80211_getmgtframe(uint8_t **frm, int headroom, int pktlen); Index: head/sys/net80211/ieee80211_scan_sw.c =================================================================== --- head/sys/net80211/ieee80211_scan_sw.c +++ head/sys/net80211/ieee80211_scan_sw.c @@ -675,19 +675,32 @@ struct ieee80211com *ic = ss->ss_ic; struct ieee80211_channel *chan; unsigned long maxdwell; - int scandone; + int scandone, scanstop; IEEE80211_LOCK(ic); end: + /* + * Note: only /end/ the scan if we're CANCEL rather than + * CANCEL+INTERRUPT (ie, 'PAUSE'). + * + * We can stop the scan if we hit cancel, but we shouldn't + * call scan_end(ss, 1) if we're just PAUSEing the scan. + */ scandone = (ss->ss_next >= ss->ss_last) || - (ss_priv->ss_iflags & ISCAN_CANCEL) != 0; + ((ss_priv->ss_iflags & ISCAN_PAUSE) == ISCAN_CANCEL); + scanstop = (ss->ss_next >= ss->ss_last) || + ((ss_priv->ss_iflags & ISCAN_CANCEL) != 0); IEEE80211_DPRINTF(ss->ss_vap, IEEE80211_MSG_SCAN, - "%s: loop start; scandone=%d\n", + "%s: loop start; scandone=%d, scanstop=%d, ss_iflags=0x%x, ss_next=%u, ss_last=%u\n", __func__, - scandone); + scandone, + scanstop, + (uint32_t) ss_priv->ss_iflags, + (uint32_t) ss->ss_next, + (uint32_t) ss->ss_last); - if (scandone || (ss->ss_flags & IEEE80211_SCAN_GOTPICK) || + if (scanstop || (ss->ss_flags & IEEE80211_SCAN_GOTPICK) || (ss_priv->ss_iflags & ISCAN_ABORT) || ieee80211_time_after(ticks + ss->ss_mindwell, ss_priv->ss_scanend)) { ss_priv->ss_iflags &= ~ISCAN_RUNNING; @@ -787,11 +800,12 @@ * Since a cancellation may have occurred during one of the * driver calls (whilst unlocked), update scandone. */ - if (scandone == 0 && (ss_priv->ss_iflags & ISCAN_CANCEL) != 0) { + if ((scandone == 0) && ((ss_priv->ss_iflags & ISCAN_PAUSE) == ISCAN_CANCEL)) { /* XXX printf? */ if_printf(vap->iv_ifp, - "%s: OOPS! scan cancelled during driver call (1)!\n", - __func__); + "%s: OOPS! scan cancelled during driver call (1) (ss_iflags=0x%x)!\n", + __func__, + ss_priv->ss_iflags); scandone = 1; } @@ -856,11 +870,12 @@ * Since a cancellation may have occurred during one of the * driver calls (whilst unlocked), update scandone. */ - if (scandone == 0 && (ss_priv->ss_iflags & ISCAN_CANCEL) != 0) { + if (scandone == 0 && (ss_priv->ss_iflags & ISCAN_PAUSE) == ISCAN_CANCEL) { /* XXX printf? */ if_printf(vap->iv_ifp, - "%s: OOPS! scan cancelled during driver call (2)!\n", - __func__); + "%s: OOPS! scan cancelled during driver call (2) (ss_iflags=0x%x)!\n", + __func__, + ss_priv->ss_iflags); scandone = 1; } @@ -900,11 +915,18 @@ */ if ((vap->iv_flags_ext & IEEE80211_FEXT_SCAN_OFFLOAD) == 0) vap->iv_sta_ps(vap, 0); - if (ss->ss_next >= ss->ss_last) + if (ss->ss_next >= ss->ss_last) { + IEEE80211_DPRINTF(vap, IEEE80211_MSG_SCAN, + "%s: Dropping out of scan; ss_next=%u, ss_last=%u\n", + __func__, + (uint32_t) ss->ss_next, + (uint32_t) ss->ss_last); ic->ic_flags_ext &= ~IEEE80211_FEXT_BGSCAN; + } /* send 'scan done' event if not interrupted due to traffic. */ - if (!(ss_priv->ss_iflags & ISCAN_INTERRUPT)) + if (!(ss_priv->ss_iflags & ISCAN_INTERRUPT) || + (ss->ss_next >= ss->ss_last)) ieee80211_notify_scan_done(vap); } ss_priv->ss_iflags &= ~(ISCAN_PAUSE | ISCAN_ABORT);