aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h2
-rw-r--r--net/mac80211/mlme.c85
2 files changed, 52 insertions, 35 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ce566f3e0169..8e53ce7ed444 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -102,7 +102,7 @@ struct ieee80211_sta_bss {
102 u64 timestamp; 102 u64 timestamp;
103 int beacon_int; 103 int beacon_int;
104 104
105 int probe_resp; 105 bool probe_resp;
106 unsigned long last_update; 106 unsigned long last_update;
107 107
108 /* during assocation, we save an ERP value from a probe response so 108 /* during assocation, we save an ERP value from a probe response so
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index e3f2cb086588..6b75cb6c6300 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2588,22 +2588,29 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2588#endif 2588#endif
2589 } 2589 }
2590 2590
2591 bss->band = rx_status->band;
2592
2593 if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
2594 bss->probe_resp && beacon) {
2595 /* STA mode:
2596 * Do not allow beacon to override data from Probe Response. */
2597 ieee80211_rx_bss_put(dev, bss);
2598 return;
2599 }
2600
2601 /* save the ERP value so that it is available at association time */ 2591 /* save the ERP value so that it is available at association time */
2602 if (elems.erp_info && elems.erp_info_len >= 1) { 2592 if (elems.erp_info && elems.erp_info_len >= 1) {
2603 bss->erp_value = elems.erp_info[0]; 2593 bss->erp_value = elems.erp_info[0];
2604 bss->has_erp_value = 1; 2594 bss->has_erp_value = 1;
2605 } 2595 }
2606 2596
2597 if (elems.ht_cap_elem &&
2598 (!bss->ht_ie || bss->ht_ie_len != elems.ht_cap_elem_len ||
2599 memcmp(bss->ht_ie, elems.ht_cap_elem, elems.ht_cap_elem_len))) {
2600 kfree(bss->ht_ie);
2601 bss->ht_ie = kmalloc(elems.ht_cap_elem_len + 2, GFP_ATOMIC);
2602 if (bss->ht_ie) {
2603 memcpy(bss->ht_ie, elems.ht_cap_elem - 2,
2604 elems.ht_cap_elem_len + 2);
2605 bss->ht_ie_len = elems.ht_cap_elem_len + 2;
2606 } else
2607 bss->ht_ie_len = 0;
2608 } else if (!elems.ht_cap_elem && bss->ht_ie) {
2609 kfree(bss->ht_ie);
2610 bss->ht_ie = NULL;
2611 bss->ht_ie_len = 0;
2612 }
2613
2607 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); 2614 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
2608 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); 2615 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
2609 2616
@@ -2625,6 +2632,26 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2625 bss->supp_rates_len += clen; 2632 bss->supp_rates_len += clen;
2626 } 2633 }
2627 2634
2635 bss->band = rx_status->band;
2636
2637 bss->timestamp = beacon_timestamp;
2638 bss->last_update = jiffies;
2639 bss->rssi = rx_status->ssi;
2640 bss->signal = rx_status->signal;
2641 bss->noise = rx_status->noise;
2642 if (!beacon && !bss->probe_resp)
2643 bss->probe_resp = true;
2644
2645 /*
2646 * In STA mode, the remaining parameters should not be overridden
2647 * by beacons because they're not necessarily accurate there.
2648 */
2649 if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
2650 bss->probe_resp && beacon) {
2651 ieee80211_rx_bss_put(dev, bss);
2652 return;
2653 }
2654
2628 if (elems.wpa && 2655 if (elems.wpa &&
2629 (!bss->wpa_ie || bss->wpa_ie_len != elems.wpa_len || 2656 (!bss->wpa_ie || bss->wpa_ie_len != elems.wpa_len ||
2630 memcmp(bss->wpa_ie, elems.wpa, elems.wpa_len))) { 2657 memcmp(bss->wpa_ie, elems.wpa, elems.wpa_len))) {
@@ -2657,6 +2684,20 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2657 bss->rsn_ie_len = 0; 2684 bss->rsn_ie_len = 0;
2658 } 2685 }
2659 2686
2687 /*
2688 * Cf.
2689 * http://www.wipo.int/pctdb/en/wo.jsp?wo=2007047181&IA=WO2007047181&DISPLAY=DESC
2690 *
2691 * quoting:
2692 *
2693 * In particular, "Wi-Fi CERTIFIED for WMM - Support for Multimedia
2694 * Applications with Quality of Service in Wi-Fi Networks," Wi- Fi
2695 * Alliance (September 1, 2004) is incorporated by reference herein.
2696 * The inclusion of the WMM Parameters in probe responses and
2697 * association responses is mandatory for WMM enabled networks. The
2698 * inclusion of the WMM Parameters in beacons, however, is optional.
2699 */
2700
2660 if (elems.wmm_param && 2701 if (elems.wmm_param &&
2661 (!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_param_len || 2702 (!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_param_len ||
2662 memcmp(bss->wmm_ie, elems.wmm_param, elems.wmm_param_len))) { 2703 memcmp(bss->wmm_ie, elems.wmm_param, elems.wmm_param_len))) {
@@ -2673,30 +2714,6 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2673 bss->wmm_ie = NULL; 2714 bss->wmm_ie = NULL;
2674 bss->wmm_ie_len = 0; 2715 bss->wmm_ie_len = 0;
2675 } 2716 }
2676 if (elems.ht_cap_elem &&
2677 (!bss->ht_ie || bss->ht_ie_len != elems.ht_cap_elem_len ||
2678 memcmp(bss->ht_ie, elems.ht_cap_elem, elems.ht_cap_elem_len))) {
2679 kfree(bss->ht_ie);
2680 bss->ht_ie = kmalloc(elems.ht_cap_elem_len + 2, GFP_ATOMIC);
2681 if (bss->ht_ie) {
2682 memcpy(bss->ht_ie, elems.ht_cap_elem - 2,
2683 elems.ht_cap_elem_len + 2);
2684 bss->ht_ie_len = elems.ht_cap_elem_len + 2;
2685 } else
2686 bss->ht_ie_len = 0;
2687 } else if (!elems.ht_cap_elem && bss->ht_ie) {
2688 kfree(bss->ht_ie);
2689 bss->ht_ie = NULL;
2690 bss->ht_ie_len = 0;
2691 }
2692
2693 bss->timestamp = beacon_timestamp;
2694 bss->last_update = jiffies;
2695 bss->rssi = rx_status->ssi;
2696 bss->signal = rx_status->signal;
2697 bss->noise = rx_status->noise;
2698 if (!beacon)
2699 bss->probe_resp++;
2700 2717
2701 /* check if we need to merge IBSS */ 2718 /* check if we need to merge IBSS */
2702 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon && 2719 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&