diff --git a/bes2600/scan.c b/bes2600/scan.c index faa1c90..ad5033b 100644 --- a/bes2600/scan.c +++ b/bes2600/scan.c @@ -22,9 +22,17 @@ * After this many consecutive WSM scan rejections from firmware, stop * issuing new scans for BES2600_SCAN_BACKOFF_JIFFIES and let the state * that's rejecting them (coex window, firmware-internal busy) clear. + * + * The backoff has to be at least as long as the natural mac80211 scan- + * retry cadence, otherwise the next attempt lands outside the window + * and bypasses the defer guard. Observed in the wild on PineTab2: + * roam-evaluation bursts at ~12 s cadence, idle background scans at + * ~5 min cadence. 30 s catches the burst and leaves the slow case + * alone (the firmware-policy state has had minutes to clear by then + * anyway). */ #define BES2600_SCAN_REJECT_THRESHOLD 3 -#define BES2600_SCAN_BACKOFF_JIFFIES (10 * HZ) +#define BES2600_SCAN_BACKOFF_JIFFIES (30 * HZ) static void bes2600_scan_restart_delayed(struct bes2600_vif *priv); @@ -40,7 +48,9 @@ static void bes2600_scan_restart_delayed(struct bes2600_vif *priv); * 2. We already saw >= BES2600_SCAN_REJECT_THRESHOLD consecutive * rejections on recent scan attempts and the backoff window has * not yet elapsed. Whatever was rejecting them is likely still - * rejecting them; give it time. + * rejecting them; give it time. If the backoff has elapsed without + * a fresh reject refreshing it, the burst is over and we reset the + * count so an isolated reject doesn't immediately re-trip. * * Returns true if the caller should abandon the scan iteration. */ @@ -51,6 +61,9 @@ static bool bes2600_scan_should_defer(struct bes2600_common *hw_priv) return true; #endif + if (time_after(jiffies, hw_priv->scan.backoff_until)) + hw_priv->scan.reject_count = 0; + if (hw_priv->scan.reject_count >= BES2600_SCAN_REJECT_THRESHOLD && time_before(jiffies, hw_priv->scan.backoff_until)) return true;