tags 795722 + pending thanks On Sun, Aug 16, 2015 at 02:50:41PM +0200, Steinar H. Gunderson wrote: > wpasupplicant upstream recently included a series of patches to improve > selection significantly: > > > https://w1.fi/cgit/hostap/commit/wpa_supplicant/scan.c?id=f0d0a5d23bd406a60358add9fa101b49dc9f9039 > > > https://w1.fi/cgit/hostap/commit/wpa_supplicant/scan.c?id=a1b790eb9d7514d1a6e0582a07f695a1564caa59 > > > https://w1.fi/cgit/hostap/commit/wpa_supplicant/scan.c?id=8b2b718da9884d66684befe99d1fbdd9abe5fb5e > > > https://w1.fi/cgit/hostap/commit/wpa_supplicant/scan.c?id=aa517ae22784aff08d3d9e38ad101b4b5c9828fb > > I've run with all of these four patches now for a few months, and it works > great for me. I also got reports from DC15 that it helped performance there. > Please consider applying them on top of 2.3.
Hi, I've made an NMU to DELAYED/7-day to address these issues. Please see included NMU diff. /* Steinar */ -- Homepage: http://www.sesse.net/
diff -Nru wpa-2.3/debian/changelog wpa-2.3/debian/changelog --- wpa-2.3/debian/changelog 2015-04-23 05:36:51.000000000 +0200 +++ wpa-2.3/debian/changelog 2015-08-30 15:30:35.000000000 +0200 @@ -1,3 +1,11 @@ +wpa (2.3-2.1) unstable; urgency=medium + + * Non-maintainer upload. + * Import four patches from upstream git (wpasupplicant_band_selection_*.patch), + manually unfuzzed, to improve 2.4/5 GHz band selection. (Closes: #795722) + + -- Steinar H. Gunderson <[email protected]> Sun, 30 Aug 2015 14:47:56 +0200 + wpa (2.3-2) unstable; urgency=high * remove Kel Modderman from Uploaders as per his request, many thanks for diff -Nru wpa-2.3/debian/patches/series wpa-2.3/debian/patches/series --- wpa-2.3/debian/patches/series 2015-04-23 05:09:52.000000000 +0200 +++ wpa-2.3/debian/patches/series 2015-08-30 14:47:45.000000000 +0200 @@ -9,3 +9,7 @@ hostapd_fix-hostapd-operation-without-hw_mode-driver-data.patch wpasupplicant_fix-systemd-unit-dependencies.patch wpasupplicant_P2P-Validate-SSID-element-length-before-copying-it-C.patch +wpasupplicant_band_selection_f0d0a5d2.patch +wpasupplicant_band_selection_a1b790eb.patch +wpasupplicant_band_selection_8b2b718d.patch +wpasupplicant_band_selection_aa517ae2.patch diff -Nru wpa-2.3/debian/patches/wpasupplicant_band_selection_8b2b718d.patch wpa-2.3/debian/patches/wpasupplicant_band_selection_8b2b718d.patch --- wpa-2.3/debian/patches/wpasupplicant_band_selection_8b2b718d.patch 1970-01-01 01:00:00.000000000 +0100 +++ wpa-2.3/debian/patches/wpasupplicant_band_selection_8b2b718d.patch 2015-08-30 15:29:45.000000000 +0200 @@ -0,0 +1,25 @@ +commit 8b2b718da9884d66684befe99d1fbdd9abe5fb5e +Author: Jouni Malinen <[email protected]> +Date: Sat Feb 28 16:35:07 2015 +0200 + + Fix minor issue in HT40 max rate determination + + Commit a1b790eb9d7514d1a6e0582a07f695a1564caa59 ('Select AP based on + estimated maximum throughput') had a copy-paste bug than ended up + leaving one of the max_ht40_rate() cases unreachable. (CID 106087) + + Signed-off-by: Jouni Malinen <[email protected]> + +Index: wpa-2.3/wpa_supplicant/scan.c +=================================================================== +--- wpa-2.3.orig/wpa_supplicant/scan.c ++++ wpa-2.3/wpa_supplicant/scan.c +@@ -1810,7 +1810,7 @@ static unsigned int max_ht40_rate(int sn + return 81000; /* HT40 MCS4 */ + if (snr < 22) + return 108000; /* HT40 MCS5 */ +- if (snr < 22) ++ if (snr < 24) + return 121500; /* HT40 MCS6 */ + return 135000; /* HT40 MCS7 */ + } diff -Nru wpa-2.3/debian/patches/wpasupplicant_band_selection_a1b790eb.patch wpa-2.3/debian/patches/wpasupplicant_band_selection_a1b790eb.patch --- wpa-2.3/debian/patches/wpasupplicant_band_selection_a1b790eb.patch 1970-01-01 01:00:00.000000000 +0100 +++ wpa-2.3/debian/patches/wpasupplicant_band_selection_a1b790eb.patch 2015-08-30 15:29:42.000000000 +0200 @@ -0,0 +1,369 @@ +commit a1b790eb9d7514d1a6e0582a07f695a1564caa59 +Author: Jouni Malinen <[email protected]> +Date: Sat Feb 21 22:53:42 2015 +0200 + + Select AP based on estimated maximum throughput + + This modifies the BSS selection routines to calculate SNR and estimated + throughput for each scan result and then use the estimated throughput as + a criteria for sorting the results. This extends the earlier design by + taking into account higher throughput rates if both the AP and local + device supports HT20, HT40, or VHT80. In addition, the maximum rate is + restricted based on SNR. + + In practice, this gives significantly higher probability of selecting + HT/VHT APs when there are multiple BSSes in the same ESS and SNR is not + low enough to prevent higher MCS use. + + Signed-off-by: Jouni Malinen <[email protected]> + +Index: wpa-2.3/src/drivers/driver.h +=================================================================== +--- wpa-2.3.orig/src/drivers/driver.h ++++ wpa-2.3/src/drivers/driver.h +@@ -202,6 +202,9 @@ struct hostapd_hw_modes { + * @tsf: Timestamp + * @age: Age of the information in milliseconds (i.e., how many milliseconds + * ago the last Beacon or Probe Response frame was received) ++ * @est_throughput: Estimated throughput in kbps (this is calculated during ++ * scan result processing if left zero by the driver wrapper) ++ * @snr: Signal-to-noise ratio in dB (calculated during scan result processing) + * @ie_len: length of the following IE field in octets + * @beacon_ie_len: length of the following Beacon IE field in octets + * +@@ -225,6 +228,8 @@ struct wpa_scan_res { + int level; + u64 tsf; + unsigned int age; ++ unsigned int est_throughput; ++ int snr; + size_t ie_len; + size_t beacon_ie_len; + /* +Index: wpa-2.3/wpa_supplicant/scan.c +=================================================================== +--- wpa-2.3.orig/wpa_supplicant/scan.c ++++ wpa-2.3/wpa_supplicant/scan.c +@@ -1554,8 +1554,8 @@ static int wpa_scan_result_compar(const + struct wpa_scan_res **_wb = (void *) b; + struct wpa_scan_res *wa = *_wa; + struct wpa_scan_res *wb = *_wb; +- int wpa_a, wpa_b, maxrate_a, maxrate_b; +- int snr_a, snr_b; ++ int wpa_a, wpa_b; ++ int snr_a, snr_b, snr_a_full, snr_b_full; + + /* WPA/WPA2 support preferred */ + wpa_a = wpa_scan_get_vendor_ie(wa, WPA_IE_VENDOR_TYPE) != NULL || +@@ -1577,22 +1577,22 @@ static int wpa_scan_result_compar(const + return -1; + + if (wa->flags & wb->flags & WPA_SCAN_LEVEL_DBM) { +- snr_a = MIN(wa->level - wa->noise, GREAT_SNR); +- snr_b = MIN(wb->level - wb->noise, GREAT_SNR); ++ snr_a_full = wa->snr; ++ snr_a = MIN(wa->snr, GREAT_SNR); ++ snr_b_full = wb->snr; ++ snr_b = MIN(wa->snr, GREAT_SNR); + } else { + /* Level is not in dBm, so we can't calculate + * SNR. Just use raw level (units unknown). */ +- snr_a = wa->level; +- snr_b = wb->level; ++ snr_a = snr_a_full = wa->level; ++ snr_b = snr_b_full = wb->level; + } + + /* if SNR is close, decide by max rate or frequency band */ + if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) || + (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) { +- maxrate_a = wpa_scan_get_max_rate(wa); +- maxrate_b = wpa_scan_get_max_rate(wb); +- if (maxrate_a != maxrate_b) +- return maxrate_b - maxrate_a; ++ if (wa->est_throughput != wb->est_throughput) ++ return wb->est_throughput - wa->est_throughput; + if (IS_5GHZ(wa->freq) ^ IS_5GHZ(wb->freq)) + return IS_5GHZ(wa->freq) ? -1 : 1; + } +@@ -1600,9 +1600,9 @@ static int wpa_scan_result_compar(const + /* all things being equal, use SNR; if SNRs are + * identical, use quality values since some drivers may only report + * that value and leave the signal level zero */ +- if (snr_b == snr_a) ++ if (snr_b_full == snr_a_full) + return wb->qual - wa->qual; +- return snr_b - snr_a; ++ return snr_b_full - snr_a_full; + #undef MIN + } + +@@ -1669,20 +1669,21 @@ static void dump_scan_res(struct wpa_sca + struct wpa_scan_res *r = scan_res->res[i]; + u8 *pos; + if (r->flags & WPA_SCAN_LEVEL_DBM) { +- int snr = r->level - r->noise; + int noise_valid = !(r->flags & WPA_SCAN_NOISE_INVALID); + + wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d " +- "noise=%d%s level=%d snr=%d%s flags=0x%x age=%u", ++ "noise=%d%s level=%d snr=%d%s flags=0x%x age=%u est=%u", + MAC2STR(r->bssid), r->freq, r->qual, + r->noise, noise_valid ? "" : "~", r->level, +- snr, snr >= GREAT_SNR ? "*" : "", r->flags, +- r->age); ++ r->snr, r->snr >= GREAT_SNR ? "*" : "", ++ r->flags, ++ r->age, r->est_throughput); + } else { + wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d " +- "noise=%d level=%d flags=0x%x age=%u", ++ "noise=%d level=%d flags=0x%x age=%u est=%u", + MAC2STR(r->bssid), r->freq, r->qual, +- r->noise, r->level, r->flags, r->age); ++ r->noise, r->level, r->flags, r->age, ++ r->est_throughput); + } + pos = (u8 *) (r + 1); + if (r->ie_len) +@@ -1757,6 +1758,180 @@ static void filter_scan_res(struct wpa_s + #define DEFAULT_NOISE_FLOOR_2GHZ (-89) + #define DEFAULT_NOISE_FLOOR_5GHZ (-92) + ++static void scan_snr(struct wpa_scan_res *res) ++{ ++ if (res->flags & WPA_SCAN_NOISE_INVALID) { ++ res->noise = IS_5GHZ(res->freq) ? ++ DEFAULT_NOISE_FLOOR_5GHZ : ++ DEFAULT_NOISE_FLOOR_2GHZ; ++ } ++ ++ if (res->flags & WPA_SCAN_LEVEL_DBM) { ++ res->snr = res->level - res->noise; ++ } else { ++ /* Level is not in dBm, so we can't calculate ++ * SNR. Just use raw level (units unknown). */ ++ res->snr = res->level; ++ } ++} ++ ++ ++static unsigned int max_ht20_rate(int snr) ++{ ++ if (snr < 6) ++ return 6500; /* HT20 MCS0 */ ++ if (snr < 8) ++ return 13000; /* HT20 MCS1 */ ++ if (snr < 13) ++ return 19500; /* HT20 MCS2 */ ++ if (snr < 17) ++ return 26000; /* HT20 MCS3 */ ++ if (snr < 20) ++ return 39000; /* HT20 MCS4 */ ++ if (snr < 23) ++ return 52000; /* HT20 MCS5 */ ++ if (snr < 24) ++ return 58500; /* HT20 MCS6 */ ++ return 65000; /* HT20 MCS7 */ ++} ++ ++ ++static unsigned int max_ht40_rate(int snr) ++{ ++ if (snr < 3) ++ return 13500; /* HT40 MCS0 */ ++ if (snr < 6) ++ return 27000; /* HT40 MCS1 */ ++ if (snr < 10) ++ return 40500; /* HT40 MCS2 */ ++ if (snr < 15) ++ return 54000; /* HT40 MCS3 */ ++ if (snr < 17) ++ return 81000; /* HT40 MCS4 */ ++ if (snr < 22) ++ return 108000; /* HT40 MCS5 */ ++ if (snr < 22) ++ return 121500; /* HT40 MCS6 */ ++ return 135000; /* HT40 MCS7 */ ++} ++ ++ ++static unsigned int max_vht80_rate(int snr) ++{ ++ if (snr < 1) ++ return 0; ++ if (snr < 2) ++ return 29300; /* VHT80 MCS0 */ ++ if (snr < 5) ++ return 58500; /* VHT80 MCS1 */ ++ if (snr < 9) ++ return 87800; /* VHT80 MCS2 */ ++ if (snr < 11) ++ return 117000; /* VHT80 MCS3 */ ++ if (snr < 15) ++ return 175500; /* VHT80 MCS4 */ ++ if (snr < 16) ++ return 234000; /* VHT80 MCS5 */ ++ if (snr < 18) ++ return 263300; /* VHT80 MCS6 */ ++ if (snr < 20) ++ return 292500; /* VHT80 MCS7 */ ++ if (snr < 22) ++ return 351000; /* VHT80 MCS8 */ ++ return 390000; /* VHT80 MCS9 */ ++} ++ ++ ++static void scan_est_throughput(struct wpa_supplicant *wpa_s, ++ struct wpa_scan_res *res) ++{ ++ enum local_hw_capab capab = wpa_s->hw_capab; ++ int rate; /* max legacy rate in 500 kb/s units */ ++ const u8 *ie; ++ unsigned int est, tmp; ++ int snr = res->snr; ++ ++ if (res->est_throughput) ++ return; ++ ++ /* Get maximum legacy rate */ ++ rate = wpa_scan_get_max_rate(res); ++ ++ /* Limit based on estimated SNR */ ++ if (rate > 1 * 2 && snr < 1) ++ rate = 1 * 2; ++ else if (rate > 2 * 2 && snr < 4) ++ rate = 2 * 2; ++ else if (rate > 6 * 2 && snr < 5) ++ rate = 6 * 2; ++ else if (rate > 9 * 2 && snr < 6) ++ rate = 9 * 2; ++ else if (rate > 12 * 2 && snr < 7) ++ rate = 12 * 2; ++ else if (rate > 18 * 2 && snr < 10) ++ rate = 18 * 2; ++ else if (rate > 24 * 2 && snr < 11) ++ rate = 24 * 2; ++ else if (rate > 36 * 2 && snr < 15) ++ rate = 36 * 2; ++ else if (rate > 48 * 2 && snr < 19) ++ rate = 48 * 2; ++ else if (rate > 54 * 2 && snr < 21) ++ rate = 54 * 2; ++ est = rate * 500; ++ ++ if (capab == CAPAB_HT || capab == CAPAB_HT40 || capab == CAPAB_VHT) { ++ ie = wpa_scan_get_ie(res, WLAN_EID_HT_CAP); ++ if (ie) { ++ tmp = max_ht20_rate(snr); ++ if (tmp > est) ++ est = tmp; ++ } ++ } ++ ++ if (capab == CAPAB_HT40 || capab == CAPAB_VHT) { ++ ie = wpa_scan_get_ie(res, WLAN_EID_HT_OPERATION); ++ if (ie && ie[1] >= 2 && ++ (ie[3] & HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) { ++ tmp = max_ht40_rate(snr); ++ if (tmp > est) ++ est = tmp; ++ } ++ } ++ ++ if (capab == CAPAB_VHT) { ++ /* Use +1 to assume VHT is always faster than HT */ ++ ie = wpa_scan_get_ie(res, WLAN_EID_VHT_CAP); ++ if (ie) { ++ tmp = max_ht20_rate(snr) + 1; ++ if (tmp > est) ++ est = tmp; ++ ++ ie = wpa_scan_get_ie(res, WLAN_EID_HT_OPERATION); ++ if (ie && ie[1] >= 2 && ++ (ie[3] & ++ HT_INFO_HT_PARAM_SECONDARY_CHNL_OFF_MASK)) { ++ tmp = max_ht40_rate(snr) + 1; ++ if (tmp > est) ++ est = tmp; ++ } ++ ++ ie = wpa_scan_get_ie(res, WLAN_EID_VHT_OPERATION); ++ if (ie && ie[1] >= 1 && ++ (ie[2] & VHT_OPMODE_CHANNEL_WIDTH_MASK)) { ++ tmp = max_vht80_rate(snr) + 1; ++ if (tmp > est) ++ est = tmp; ++ } ++ } ++ } ++ ++ /* TODO: channel utilization and AP load (e.g., from AP Beacon) */ ++ ++ res->est_throughput = est; ++} ++ ++ + /** + * wpa_supplicant_get_scan_results - Get scan results + * @wpa_s: Pointer to wpa_supplicant data +@@ -1793,12 +1968,8 @@ wpa_supplicant_get_scan_results(struct w + for (i = 0; i < scan_res->num; i++) { + struct wpa_scan_res *scan_res_item = scan_res->res[i]; + +- if (scan_res_item->flags & WPA_SCAN_NOISE_INVALID) { +- scan_res_item->noise = +- IS_5GHZ(scan_res_item->freq) ? +- DEFAULT_NOISE_FLOOR_5GHZ : +- DEFAULT_NOISE_FLOOR_2GHZ; +- } ++ scan_snr(scan_res_item); ++ scan_est_throughput(wpa_s, scan_res_item); + } + + #ifdef CONFIG_WPS +Index: wpa-2.3/wpa_supplicant/wpa_supplicant.c +=================================================================== +--- wpa-2.3.orig/wpa_supplicant/wpa_supplicant.c ++++ wpa-2.3/wpa_supplicant/wpa_supplicant.c +@@ -3759,6 +3759,23 @@ static int wpa_supplicant_init_iface(str + wpa_s->hw.modes = wpa_drv_get_hw_feature_data(wpa_s, + &wpa_s->hw.num_modes, + &wpa_s->hw.flags); ++ if (wpa_s->hw.modes) { ++ u16 i; ++ ++ for (i = 0; i < wpa_s->hw.num_modes; i++) { ++ if (wpa_s->hw.modes[i].vht_capab) { ++ wpa_s->hw_capab = CAPAB_VHT; ++ break; ++ } ++ ++ if (wpa_s->hw.modes[i].ht_capab & ++ HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) ++ wpa_s->hw_capab = CAPAB_HT40; ++ else if (wpa_s->hw.modes[i].ht_capab && ++ wpa_s->hw_capab == CAPAB_NO_HT_VHT) ++ wpa_s->hw_capab = CAPAB_HT; ++ } ++ } + + if (wpa_drv_get_capa(wpa_s, &capa) == 0) { + wpa_s->drv_capa_known = 1; +Index: wpa-2.3/wpa_supplicant/wpa_supplicant_i.h +=================================================================== +--- wpa-2.3.orig/wpa_supplicant/wpa_supplicant_i.h ++++ wpa-2.3/wpa_supplicant/wpa_supplicant_i.h +@@ -825,6 +825,12 @@ struct wpa_supplicant { + u16 num_modes; + u16 flags; + } hw; ++ enum local_hw_capab { ++ CAPAB_NO_HT_VHT, ++ CAPAB_HT, ++ CAPAB_HT40, ++ CAPAB_VHT, ++ } hw_capab; + #ifdef CONFIG_MACSEC + struct ieee802_1x_kay *kay; + #endif /* CONFIG_MACSEC */ diff -Nru wpa-2.3/debian/patches/wpasupplicant_band_selection_f0d0a5d2.patch wpa-2.3/debian/patches/wpasupplicant_band_selection_f0d0a5d2.patch --- wpa-2.3/debian/patches/wpasupplicant_band_selection_f0d0a5d2.patch 1970-01-01 01:00:00.000000000 +0100 +++ wpa-2.3/debian/patches/wpasupplicant_band_selection_f0d0a5d2.patch 2015-08-30 15:28:22.000000000 +0200 @@ -0,0 +1,158 @@ +commit f0d0a5d23bd406a60358add9fa101b49dc9f9039 +Author: Mukesh Agrawal <[email protected]> +Date: Tue Apr 8 17:54:49 2014 -0700 + + Improve BSS selection with default noise floor values + + When noise floor measurements are not available, compute SNR + using default values for the noise floor. This helps steer us + towards 5 GHz BSSes in high signal strength environments. + + In more detail... + + Existing code prefers a 5 GHz BSS when the 5 GHz BSS's signal + strength is "close" to that of the 2.4 GHz BSS, or when both SNRs + are large. However, the mwifiex driver does not provide noise + floor measurements, so we can't compute SNRs. + + Because mwifiex doesn't provide NF measurements, the "large SNR" + code wasn't effective. By using default values for the noise floor, + we can again compute SNRs, and decide that the SNR is high enough + that we shouldn't worry about the exact difference in SNR. + + The default noise floor values (one for 2.4 GHz, and one for 5 GHz) + were chosen by measurement in a noisy environment, so they should be + conservative. + + Note that while this patch is motivated by mwifiex, it affects + ath9k as well. Although ath9k provides noise floor measurements + in general, it will sometimes fail to provide a measurement for + one or more specific channels. + + As a result of this patch, we'll always compare BSSes based on SNR + (either measured or estimated), rather than sometimes comparing + based on signal strength. ("Always" assumes that the + WPA_SCAN_LEVEL_DBM flag is set. It is for mwifiex and ath9k.) + + While there: + - fix a whitespace issue (spaces -> tab) + - clean up existing comments + - update dump_scan_res to indicate whether the noise floor is + measured, or default + + Signed-hostap: mukesh agrawal <[email protected]> + +Index: wpa-2.3/wpa_supplicant/scan.c +=================================================================== +--- wpa-2.3.orig/wpa_supplicant/scan.c ++++ wpa-2.3/wpa_supplicant/scan.c +@@ -1543,11 +1543,12 @@ struct wpabuf * wpa_scan_get_vendor_ie_m + */ + #define GREAT_SNR 30 + ++#define IS_5GHZ(n) (n > 4000) ++ + /* Compare function for sorting scan results. Return >0 if @b is considered + * better. */ + static int wpa_scan_result_compar(const void *a, const void *b) + { +-#define IS_5GHZ(n) (n > 4000) + #define MIN(a,b) a < b ? a : b + struct wpa_scan_res **_wa = (void *) a; + struct wpa_scan_res **_wb = (void *) b; +@@ -1575,18 +1576,18 @@ static int wpa_scan_result_compar(const + (wb->caps & IEEE80211_CAP_PRIVACY) == 0) + return -1; + +- if ((wa->flags & wb->flags & WPA_SCAN_LEVEL_DBM) && +- !((wa->flags | wb->flags) & WPA_SCAN_NOISE_INVALID)) { ++ if (wa->flags & wb->flags & WPA_SCAN_LEVEL_DBM) { + snr_a = MIN(wa->level - wa->noise, GREAT_SNR); + snr_b = MIN(wb->level - wb->noise, GREAT_SNR); + } else { +- /* Not suitable information to calculate SNR, so use level */ ++ /* Level is not in dBm, so we can't calculate ++ * SNR. Just use raw level (units unknown). */ + snr_a = wa->level; + snr_b = wb->level; + } + +- /* best/max rate preferred if SNR close enough */ +- if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) || ++ /* if SNR is close, decide by max rate or frequency band */ ++ if ((snr_a && snr_b && abs(snr_b - snr_a) < 5) || + (wa->qual && wb->qual && abs(wb->qual - wa->qual) < 10)) { + maxrate_a = wpa_scan_get_max_rate(wa); + maxrate_b = wpa_scan_get_max_rate(wb); +@@ -1596,8 +1597,6 @@ static int wpa_scan_result_compar(const + return IS_5GHZ(wa->freq) ? -1 : 1; + } + +- /* use freq for channel preference */ +- + /* all things being equal, use SNR; if SNRs are + * identical, use quality values since some drivers may only report + * that value and leave the signal level zero */ +@@ -1605,7 +1604,6 @@ static int wpa_scan_result_compar(const + return wb->qual - wa->qual; + return snr_b - snr_a; + #undef MIN +-#undef IS_5GHZ + } + + +@@ -1670,15 +1668,15 @@ static void dump_scan_res(struct wpa_sca + for (i = 0; i < scan_res->num; i++) { + struct wpa_scan_res *r = scan_res->res[i]; + u8 *pos; +- if ((r->flags & (WPA_SCAN_LEVEL_DBM | WPA_SCAN_NOISE_INVALID)) +- == WPA_SCAN_LEVEL_DBM) { ++ if (r->flags & WPA_SCAN_LEVEL_DBM) { + int snr = r->level - r->noise; ++ int noise_valid = !(r->flags & WPA_SCAN_NOISE_INVALID); ++ + wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d " +- "noise=%d level=%d snr=%d%s flags=0x%x " +- "age=%u", ++ "noise=%d%s level=%d snr=%d%s flags=0x%x age=%u", + MAC2STR(r->bssid), r->freq, r->qual, +- r->noise, r->level, snr, +- snr >= GREAT_SNR ? "*" : "", r->flags, ++ r->noise, noise_valid ? "" : "~", r->level, ++ snr, snr >= GREAT_SNR ? "*" : "", r->flags, + r->age); + } else { + wpa_printf(MSG_EXCESSIVE, MACSTR " freq=%d qual=%d " +@@ -1751,6 +1749,14 @@ static void filter_scan_res(struct wpa_s + } + + ++/* ++ * Noise floor values to use when we have signal strength ++ * measurements, but no noise floor measurments. These values were ++ * measured in an office environment with many APs. ++ */ ++#define DEFAULT_NOISE_FLOOR_2GHZ (-89) ++#define DEFAULT_NOISE_FLOOR_5GHZ (-92) ++ + /** + * wpa_supplicant_get_scan_results - Get scan results + * @wpa_s: Pointer to wpa_supplicant data +@@ -1784,6 +1790,17 @@ wpa_supplicant_get_scan_results(struct w + } + filter_scan_res(wpa_s, scan_res); + ++ for (i = 0; i < scan_res->num; i++) { ++ struct wpa_scan_res *scan_res_item = scan_res->res[i]; ++ ++ if (scan_res_item->flags & WPA_SCAN_NOISE_INVALID) { ++ scan_res_item->noise = ++ IS_5GHZ(scan_res_item->freq) ? ++ DEFAULT_NOISE_FLOOR_5GHZ : ++ DEFAULT_NOISE_FLOOR_2GHZ; ++ } ++ } ++ + #ifdef CONFIG_WPS + if (wpas_wps_searching(wpa_s)) { + wpa_dbg(wpa_s, MSG_DEBUG, "WPS: Order scan results with WPS " diff -Nru wpa-2.3/debian/patches/wpasupplicant_band_selection_aa517ae2.patch wpa-2.3/debian/patches/wpasupplicant_band_selection_aa517ae2.patch --- wpa-2.3/debian/patches/wpasupplicant_band_selection_aa517ae2.patch 1970-01-01 01:00:00.000000000 +0100 +++ wpa-2.3/debian/patches/wpasupplicant_band_selection_aa517ae2.patch 2015-08-30 15:29:47.000000000 +0200 @@ -0,0 +1,26 @@ +commit aa517ae22784aff08d3d9e38ad101b4b5c9828fb +Author: Hahn, Maital <[email protected]> +Date: Wed Jul 8 13:13:11 2015 +0000 + + wpa_supplicant: Fix a typo in wpa_scan_result_compar() + + A typo in wpa_scan_result_compar() caused wrong scan results sorting + (and wrong roaming decision). This fixes a copy-paste regression + introduced by commit a1b790eb9d7514d1a6e0582a07f695a1564caa59 ('Select + AP based on estimated maximum throughput'). + + Signed-off-by: Maital Hahn <[email protected]> + +Index: wpa-2.3/wpa_supplicant/scan.c +=================================================================== +--- wpa-2.3.orig/wpa_supplicant/scan.c ++++ wpa-2.3/wpa_supplicant/scan.c +@@ -1580,7 +1580,7 @@ static int wpa_scan_result_compar(const + snr_a_full = wa->snr; + snr_a = MIN(wa->snr, GREAT_SNR); + snr_b_full = wb->snr; +- snr_b = MIN(wa->snr, GREAT_SNR); ++ snr_b = MIN(wb->snr, GREAT_SNR); + } else { + /* Level is not in dBm, so we can't calculate + * SNR. Just use raw level (units unknown). */

