|
@@ -2588,22 +2588,29 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
- bss->band = rx_status->band;
|
|
|
-
|
|
|
- if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
|
|
|
- bss->probe_resp && beacon) {
|
|
|
- /* STA mode:
|
|
|
- * Do not allow beacon to override data from Probe Response. */
|
|
|
- ieee80211_rx_bss_put(dev, bss);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
/* save the ERP value so that it is available at association time */
|
|
|
if (elems.erp_info && elems.erp_info_len >= 1) {
|
|
|
bss->erp_value = elems.erp_info[0];
|
|
|
bss->has_erp_value = 1;
|
|
|
}
|
|
|
|
|
|
+ if (elems.ht_cap_elem &&
|
|
|
+ (!bss->ht_ie || bss->ht_ie_len != elems.ht_cap_elem_len ||
|
|
|
+ memcmp(bss->ht_ie, elems.ht_cap_elem, elems.ht_cap_elem_len))) {
|
|
|
+ kfree(bss->ht_ie);
|
|
|
+ bss->ht_ie = kmalloc(elems.ht_cap_elem_len + 2, GFP_ATOMIC);
|
|
|
+ if (bss->ht_ie) {
|
|
|
+ memcpy(bss->ht_ie, elems.ht_cap_elem - 2,
|
|
|
+ elems.ht_cap_elem_len + 2);
|
|
|
+ bss->ht_ie_len = elems.ht_cap_elem_len + 2;
|
|
|
+ } else
|
|
|
+ bss->ht_ie_len = 0;
|
|
|
+ } else if (!elems.ht_cap_elem && bss->ht_ie) {
|
|
|
+ kfree(bss->ht_ie);
|
|
|
+ bss->ht_ie = NULL;
|
|
|
+ bss->ht_ie_len = 0;
|
|
|
+ }
|
|
|
+
|
|
|
bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
|
|
|
bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
|
|
|
|
|
@@ -2625,6 +2632,26 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
|
|
|
bss->supp_rates_len += clen;
|
|
|
}
|
|
|
|
|
|
+ bss->band = rx_status->band;
|
|
|
+
|
|
|
+ bss->timestamp = beacon_timestamp;
|
|
|
+ bss->last_update = jiffies;
|
|
|
+ bss->rssi = rx_status->ssi;
|
|
|
+ bss->signal = rx_status->signal;
|
|
|
+ bss->noise = rx_status->noise;
|
|
|
+ if (!beacon && !bss->probe_resp)
|
|
|
+ bss->probe_resp = true;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * In STA mode, the remaining parameters should not be overridden
|
|
|
+ * by beacons because they're not necessarily accurate there.
|
|
|
+ */
|
|
|
+ if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
|
|
|
+ bss->probe_resp && beacon) {
|
|
|
+ ieee80211_rx_bss_put(dev, bss);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
if (elems.wpa &&
|
|
|
(!bss->wpa_ie || bss->wpa_ie_len != elems.wpa_len ||
|
|
|
memcmp(bss->wpa_ie, elems.wpa, elems.wpa_len))) {
|
|
@@ -2657,6 +2684,20 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
|
|
|
bss->rsn_ie_len = 0;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Cf.
|
|
|
+ * http://www.wipo.int/pctdb/en/wo.jsp?wo=2007047181&IA=WO2007047181&DISPLAY=DESC
|
|
|
+ *
|
|
|
+ * quoting:
|
|
|
+ *
|
|
|
+ * In particular, "Wi-Fi CERTIFIED for WMM - Support for Multimedia
|
|
|
+ * Applications with Quality of Service in Wi-Fi Networks," Wi- Fi
|
|
|
+ * Alliance (September 1, 2004) is incorporated by reference herein.
|
|
|
+ * The inclusion of the WMM Parameters in probe responses and
|
|
|
+ * association responses is mandatory for WMM enabled networks. The
|
|
|
+ * inclusion of the WMM Parameters in beacons, however, is optional.
|
|
|
+ */
|
|
|
+
|
|
|
if (elems.wmm_param &&
|
|
|
(!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_param_len ||
|
|
|
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,
|
|
|
bss->wmm_ie = NULL;
|
|
|
bss->wmm_ie_len = 0;
|
|
|
}
|
|
|
- if (elems.ht_cap_elem &&
|
|
|
- (!bss->ht_ie || bss->ht_ie_len != elems.ht_cap_elem_len ||
|
|
|
- memcmp(bss->ht_ie, elems.ht_cap_elem, elems.ht_cap_elem_len))) {
|
|
|
- kfree(bss->ht_ie);
|
|
|
- bss->ht_ie = kmalloc(elems.ht_cap_elem_len + 2, GFP_ATOMIC);
|
|
|
- if (bss->ht_ie) {
|
|
|
- memcpy(bss->ht_ie, elems.ht_cap_elem - 2,
|
|
|
- elems.ht_cap_elem_len + 2);
|
|
|
- bss->ht_ie_len = elems.ht_cap_elem_len + 2;
|
|
|
- } else
|
|
|
- bss->ht_ie_len = 0;
|
|
|
- } else if (!elems.ht_cap_elem && bss->ht_ie) {
|
|
|
- kfree(bss->ht_ie);
|
|
|
- bss->ht_ie = NULL;
|
|
|
- bss->ht_ie_len = 0;
|
|
|
- }
|
|
|
-
|
|
|
- bss->timestamp = beacon_timestamp;
|
|
|
- bss->last_update = jiffies;
|
|
|
- bss->rssi = rx_status->ssi;
|
|
|
- bss->signal = rx_status->signal;
|
|
|
- bss->noise = rx_status->noise;
|
|
|
- if (!beacon)
|
|
|
- bss->probe_resp++;
|
|
|
|
|
|
/* check if we need to merge IBSS */
|
|
|
if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
|