mac80211: use short_preamble mode from capability if ERP IE not present

When associating to a b-only AP where there is no ERP IE, short preamble
mode is left at previous state (probably also protection mode). In this
case, disable protection and use short preamble mode as specified in
capability field. The same is done if capability field is changed on-the-fly.

Signed-off-by: Vladimir Koutny <vlado@ksp.sk>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by Vladimir Koutny and committed by John W. Linville 216bce90 16f2e85d

+35 -8
+35 -8
net/mac80211/ieee80211_sta.c
··· 312 } 313 } 314 315 - 316 - static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata, 317 - u8 erp_value) 318 { 319 struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; 320 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 321 - bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; 322 - bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0; 323 DECLARE_MAC_BUF(mac); 324 u32 changed = 0; 325 ··· 343 } 344 bss_conf->use_short_preamble = use_short_preamble; 345 changed |= BSS_CHANGED_ERP_PREAMBLE; 346 } 347 348 return changed; ··· 492 local->hw.conf.channel, 493 ifsta->ssid, ifsta->ssid_len); 494 if (bss) { 495 - if (bss->has_erp_value) 496 - changed |= ieee80211_handle_erp_ie( 497 - sdata, bss->erp_value); 498 ieee80211_rx_bss_put(dev, bss); 499 } 500 ··· 2138 2139 if (elems.erp_info && elems.erp_info_len >= 1) 2140 changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]); 2141 2142 if (elems.ht_cap_elem && elems.ht_info_elem && 2143 elems.wmm_param && local->ops->conf_ht &&
··· 312 } 313 } 314 315 + static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, 316 + bool use_protection, 317 + bool use_short_preamble) 318 { 319 struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; 320 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 321 DECLARE_MAC_BUF(mac); 322 u32 changed = 0; 323 ··· 345 } 346 bss_conf->use_short_preamble = use_short_preamble; 347 changed |= BSS_CHANGED_ERP_PREAMBLE; 348 + } 349 + 350 + return changed; 351 + } 352 + 353 + static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata, 354 + u8 erp_value) 355 + { 356 + bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; 357 + bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0; 358 + 359 + return ieee80211_handle_protect_preamb(sdata, 360 + use_protection, use_short_preamble); 361 + } 362 + 363 + static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, 364 + struct ieee80211_sta_bss *bss) 365 + { 366 + u32 changed = 0; 367 + 368 + if (bss->has_erp_value) 369 + changed |= ieee80211_handle_erp_ie(sdata, bss->erp_value); 370 + else { 371 + u16 capab = bss->capability; 372 + changed |= ieee80211_handle_protect_preamb(sdata, false, 373 + (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0); 374 } 375 376 return changed; ··· 468 local->hw.conf.channel, 469 ifsta->ssid, ifsta->ssid_len); 470 if (bss) { 471 + changed |= ieee80211_handle_bss_capability(sdata, bss); 472 ieee80211_rx_bss_put(dev, bss); 473 } 474 ··· 2116 2117 if (elems.erp_info && elems.erp_info_len >= 1) 2118 changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]); 2119 + else { 2120 + u16 capab = le16_to_cpu(mgmt->u.beacon.capab_info); 2121 + changed |= ieee80211_handle_protect_preamb(sdata, false, 2122 + (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0); 2123 + } 2124 2125 if (elems.ht_cap_elem && elems.ht_info_elem && 2126 elems.wmm_param && local->ops->conf_ht &&