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 312 } 313 313 } 314 314 315 - 316 - static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata, 317 - u8 erp_value) 315 + static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, 316 + bool use_protection, 317 + bool use_short_preamble) 318 318 { 319 319 struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; 320 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 321 DECLARE_MAC_BUF(mac); 324 322 u32 changed = 0; 325 323 ··· 343 345 } 344 346 bss_conf->use_short_preamble = use_short_preamble; 345 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); 346 374 } 347 375 348 376 return changed; ··· 492 468 local->hw.conf.channel, 493 469 ifsta->ssid, ifsta->ssid_len); 494 470 if (bss) { 495 - if (bss->has_erp_value) 496 - changed |= ieee80211_handle_erp_ie( 497 - sdata, bss->erp_value); 471 + changed |= ieee80211_handle_bss_capability(sdata, bss); 498 472 ieee80211_rx_bss_put(dev, bss); 499 473 } 500 474 ··· 2138 2116 2139 2117 if (elems.erp_info && elems.erp_info_len >= 1) 2140 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 + } 2141 2124 2142 2125 if (elems.ht_cap_elem && elems.ht_info_elem && 2143 2126 elems.wmm_param && local->ops->conf_ht &&