2020-07-07 09:40:55

by P Praneesh

[permalink] [raw]
Subject: [PATCH v2] mac80211: avoid bss color setting in non-he mode

Adding bss-color configuration for HE mode alone.
Earlier we have enabled it by default, irrespective
of capabilities. But bss-color feature is only for
HE mode. Hence avoiding this by adding bss-color flag
only for HE mode.

Signed-off-by: P Praneesh <[email protected]>
---
v2:
-addressed Rajkumar's comments.
-moved remaining HE flags under
corresponding check.
---
net/mac80211/cfg.c | 8 +++++---
net/mac80211/mlme.c | 4 +++-
net/wireless/nl80211.c | 3 +++
3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 9b36054..4b98c8f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -991,9 +991,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
BSS_CHANGED_SSID |
BSS_CHANGED_P2P_PS |
BSS_CHANGED_TXPOWER |
- BSS_CHANGED_TWT |
- BSS_CHANGED_HE_OBSS_PD |
- BSS_CHANGED_HE_BSS_COLOR;
+ BSS_CHANGED_TWT;
int i, err;
int prev_beacon_int;

@@ -1019,6 +1017,10 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
sdata->vif.bss_conf.frame_time_rts_th =
le32_get_bits(params->he_oper->he_oper_params,
IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK);
+ changed |= BSS_CHANGED_HE_OBSS_PD;
+
+ if (!params->he_bss_color.disabled)
+ changed |= BSS_CHANGED_HE_BSS_COLOR;
}

mutex_lock(&local->mtx);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index b2a9d47..76ba761 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3463,7 +3463,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
bss_conf->he_bss_color.disabled =
le32_get_bits(elems->he_operation->he_oper_params,
IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED);
- changed |= BSS_CHANGED_HE_BSS_COLOR;
+
+ if (!params->he_bss_color.disabled)
+ changed |= BSS_CHANGED_HE_BSS_COLOR;

bss_conf->htc_trig_based_pkt_ext =
le32_get_bits(elems->he_operation->he_oper_params,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 263ae39..29b15dd 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5019,6 +5019,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
goto out;
}

+ /* disabling BSS color default */
+ params.he_bss_color.disabled = true;
+
if (info->attrs[NL80211_ATTR_HE_BSS_COLOR]) {
err = nl80211_parse_he_bss_color(
info->attrs[NL80211_ATTR_HE_BSS_COLOR],
--
2.7.4


2020-07-07 12:59:40

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2] mac80211: avoid bss color setting in non-he mode

Hi Praneesh,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on mac80211-next/master]
[also build test ERROR on mac80211/master v5.8-rc4 next-20200707]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/P-Praneesh/mac80211-avoid-bss-color-setting-in-non-he-mode/20200707-173732
base: https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git master
config: nios2-allyesconfig (attached as .config)
compiler: nios2-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=nios2

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

net/mac80211/mlme.c: In function 'ieee80211_assoc_success':
>> net/mac80211/mlme.c:3465:8: error: 'params' undeclared (first use in this function); did you mean 'parameq'?
3465 | if (!params->he_bss_color.disabled)
| ^~~~~~
| parameq
net/mac80211/mlme.c:3465:8: note: each undeclared identifier is reported only once for each function it appears in

vim +3465 net/mac80211/mlme.c

3250
3251 static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
3252 struct cfg80211_bss *cbss,
3253 struct ieee80211_mgmt *mgmt, size_t len,
3254 struct ieee802_11_elems *elems)
3255 {
3256 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3257 struct ieee80211_local *local = sdata->local;
3258 struct ieee80211_supported_band *sband;
3259 struct sta_info *sta;
3260 u16 capab_info, aid;
3261 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
3262 const struct cfg80211_bss_ies *bss_ies = NULL;
3263 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
3264 bool is_6ghz = cbss->channel->band == NL80211_BAND_6GHZ;
3265 u32 changed = 0;
3266 int err;
3267 bool ret;
3268
3269 /* AssocResp and ReassocResp have identical structure */
3270
3271 aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
3272 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
3273
3274 /*
3275 * The 5 MSB of the AID field are reserved
3276 * (802.11-2016 9.4.1.8 AID field)
3277 */
3278 aid &= 0x7ff;
3279
3280 ifmgd->broken_ap = false;
3281
3282 if (aid == 0 || aid > IEEE80211_MAX_AID) {
3283 sdata_info(sdata, "invalid AID value %d (out of range), turn off PS\n",
3284 aid);
3285 aid = 0;
3286 ifmgd->broken_ap = true;
3287 }
3288
3289 if (!elems->supp_rates) {
3290 sdata_info(sdata, "no SuppRates element in AssocResp\n");
3291 return false;
3292 }
3293
3294 sdata->vif.bss_conf.aid = aid;
3295 ifmgd->tdls_chan_switch_prohibited =
3296 elems->ext_capab && elems->ext_capab_len >= 5 &&
3297 (elems->ext_capab[4] & WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED);
3298
3299 /*
3300 * Some APs are erroneously not including some information in their
3301 * (re)association response frames. Try to recover by using the data
3302 * from the beacon or probe response. This seems to afflict mobile
3303 * 2G/3G/4G wifi routers, reported models include the "Onda PN51T",
3304 * "Vodafone PocketWiFi 2", "ZTE MF60" and a similar T-Mobile device.
3305 */
3306 if (!is_6ghz &&
3307 ((assoc_data->wmm && !elems->wmm_param) ||
3308 (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
3309 (!elems->ht_cap_elem || !elems->ht_operation)) ||
3310 (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
3311 (!elems->vht_cap_elem || !elems->vht_operation)))) {
3312 const struct cfg80211_bss_ies *ies;
3313 struct ieee802_11_elems bss_elems;
3314
3315 rcu_read_lock();
3316 ies = rcu_dereference(cbss->ies);
3317 if (ies)
3318 bss_ies = kmemdup(ies, sizeof(*ies) + ies->len,
3319 GFP_ATOMIC);
3320 rcu_read_unlock();
3321 if (!bss_ies)
3322 return false;
3323
3324 ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
3325 false, &bss_elems,
3326 mgmt->bssid,
3327 assoc_data->bss->bssid);
3328 if (assoc_data->wmm &&
3329 !elems->wmm_param && bss_elems.wmm_param) {
3330 elems->wmm_param = bss_elems.wmm_param;
3331 sdata_info(sdata,
3332 "AP bug: WMM param missing from AssocResp\n");
3333 }
3334
3335 /*
3336 * Also check if we requested HT/VHT, otherwise the AP doesn't
3337 * have to include the IEs in the (re)association response.
3338 */
3339 if (!elems->ht_cap_elem && bss_elems.ht_cap_elem &&
3340 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
3341 elems->ht_cap_elem = bss_elems.ht_cap_elem;
3342 sdata_info(sdata,
3343 "AP bug: HT capability missing from AssocResp\n");
3344 }
3345 if (!elems->ht_operation && bss_elems.ht_operation &&
3346 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
3347 elems->ht_operation = bss_elems.ht_operation;
3348 sdata_info(sdata,
3349 "AP bug: HT operation missing from AssocResp\n");
3350 }
3351 if (!elems->vht_cap_elem && bss_elems.vht_cap_elem &&
3352 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
3353 elems->vht_cap_elem = bss_elems.vht_cap_elem;
3354 sdata_info(sdata,
3355 "AP bug: VHT capa missing from AssocResp\n");
3356 }
3357 if (!elems->vht_operation && bss_elems.vht_operation &&
3358 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
3359 elems->vht_operation = bss_elems.vht_operation;
3360 sdata_info(sdata,
3361 "AP bug: VHT operation missing from AssocResp\n");
3362 }
3363 }
3364
3365 /*
3366 * We previously checked these in the beacon/probe response, so
3367 * they should be present here. This is just a safety net.
3368 */
3369 if (!is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
3370 (!elems->wmm_param || !elems->ht_cap_elem || !elems->ht_operation)) {
3371 sdata_info(sdata,
3372 "HT AP is missing WMM params or HT capability/operation\n");
3373 ret = false;
3374 goto out;
3375 }
3376
3377 if (!is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
3378 (!elems->vht_cap_elem || !elems->vht_operation)) {
3379 sdata_info(sdata,
3380 "VHT AP is missing VHT capability/operation\n");
3381 ret = false;
3382 goto out;
3383 }
3384
3385 if (is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_HE) &&
3386 !elems->he_6ghz_capa) {
3387 sdata_info(sdata,
3388 "HE 6 GHz AP is missing HE 6 GHz band capability\n");
3389 ret = false;
3390 goto out;
3391 }
3392
3393 mutex_lock(&sdata->local->sta_mtx);
3394 /*
3395 * station info was already allocated and inserted before
3396 * the association and should be available to us
3397 */
3398 sta = sta_info_get(sdata, cbss->bssid);
3399 if (WARN_ON(!sta)) {
3400 mutex_unlock(&sdata->local->sta_mtx);
3401 ret = false;
3402 goto out;
3403 }
3404
3405 sband = ieee80211_get_sband(sdata);
3406 if (!sband) {
3407 mutex_unlock(&sdata->local->sta_mtx);
3408 ret = false;
3409 goto out;
3410 }
3411
3412 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE) &&
3413 (!elems->he_cap || !elems->he_operation)) {
3414 mutex_unlock(&sdata->local->sta_mtx);
3415 sdata_info(sdata,
3416 "HE AP is missing HE capability/operation\n");
3417 ret = false;
3418 goto out;
3419 }
3420
3421 /* Set up internal HT/VHT capabilities */
3422 if (elems->ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
3423 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
3424 elems->ht_cap_elem, sta);
3425
3426 if (elems->vht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
3427 ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
3428 elems->vht_cap_elem, sta);
3429
3430 if (elems->he_operation && !(ifmgd->flags & IEEE80211_STA_DISABLE_HE) &&
3431 elems->he_cap) {
3432 ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband,
3433 elems->he_cap,
3434 elems->he_cap_len,
3435 elems->he_6ghz_capa,
3436 sta);
3437
3438 bss_conf->he_support = sta->sta.he_cap.has_he;
3439 if (elems->rsnx && elems->rsnx_len &&
3440 (elems->rsnx[0] & WLAN_RSNX_CAPA_PROTECTED_TWT) &&
3441 wiphy_ext_feature_isset(local->hw.wiphy,
3442 NL80211_EXT_FEATURE_PROTECTED_TWT))
3443 bss_conf->twt_protected = true;
3444 else
3445 bss_conf->twt_protected = false;
3446
3447 changed |= ieee80211_recalc_twt_req(sdata, sta, elems);
3448 } else {
3449 bss_conf->he_support = false;
3450 bss_conf->twt_requester = false;
3451 bss_conf->twt_protected = false;
3452 }
3453
3454 if (bss_conf->he_support) {
3455 bss_conf->he_bss_color.color =
3456 le32_get_bits(elems->he_operation->he_oper_params,
3457 IEEE80211_HE_OPERATION_BSS_COLOR_MASK);
3458 bss_conf->he_bss_color.partial =
3459 le32_get_bits(elems->he_operation->he_oper_params,
3460 IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR);
3461 bss_conf->he_bss_color.disabled =
3462 le32_get_bits(elems->he_operation->he_oper_params,
3463 IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED);
3464
> 3465 if (!params->he_bss_color.disabled)
3466 changed |= BSS_CHANGED_HE_BSS_COLOR;
3467
3468 bss_conf->htc_trig_based_pkt_ext =
3469 le32_get_bits(elems->he_operation->he_oper_params,
3470 IEEE80211_HE_OPERATION_DFLT_PE_DURATION_MASK);
3471 bss_conf->frame_time_rts_th =
3472 le32_get_bits(elems->he_operation->he_oper_params,
3473 IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK);
3474
3475 bss_conf->multi_sta_back_32bit =
3476 sta->sta.he_cap.he_cap_elem.mac_cap_info[2] &
3477 IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP;
3478
3479 bss_conf->ack_enabled =
3480 sta->sta.he_cap.he_cap_elem.mac_cap_info[2] &
3481 IEEE80211_HE_MAC_CAP2_ACK_EN;
3482
3483 bss_conf->uora_exists = !!elems->uora_element;
3484 if (elems->uora_element)
3485 bss_conf->uora_ocw_range = elems->uora_element[0];
3486
3487 ieee80211_he_op_ie_to_bss_conf(&sdata->vif, elems->he_operation);
3488 ieee80211_he_spr_ie_to_bss_conf(&sdata->vif, elems->he_spr);
3489 /* TODO: OPEN: what happens if BSS color disable is set? */
3490 }
3491
3492 if (cbss->transmitted_bss) {
3493 bss_conf->nontransmitted = true;
3494 ether_addr_copy(bss_conf->transmitter_bssid,
3495 cbss->transmitted_bss->bssid);
3496 bss_conf->bssid_indicator = cbss->max_bssid_indicator;
3497 bss_conf->bssid_index = cbss->bssid_index;
3498 }
3499
3500 /*
3501 * Some APs, e.g. Netgear WNDR3700, report invalid HT operation data
3502 * in their association response, so ignore that data for our own
3503 * configuration. If it changed since the last beacon, we'll get the
3504 * next beacon and update then.
3505 */
3506
3507 /*
3508 * If an operating mode notification IE is present, override the
3509 * NSS calculation (that would be done in rate_control_rate_init())
3510 * and use the # of streams from that element.
3511 */
3512 if (elems->opmode_notif &&
3513 !(*elems->opmode_notif & IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF)) {
3514 u8 nss;
3515
3516 nss = *elems->opmode_notif & IEEE80211_OPMODE_NOTIF_RX_NSS_MASK;
3517 nss >>= IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
3518 nss += 1;
3519 sta->sta.rx_nss = nss;
3520 }
3521
3522 rate_control_rate_init(sta);
3523
3524 if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) {
3525 set_sta_flag(sta, WLAN_STA_MFP);
3526 sta->sta.mfp = true;
3527 } else {
3528 sta->sta.mfp = false;
3529 }
3530
3531 sta->sta.wme = elems->wmm_param && local->hw.queues >= IEEE80211_NUM_ACS;
3532
3533 err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
3534 if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
3535 err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
3536 if (err) {
3537 sdata_info(sdata,
3538 "failed to move station %pM to desired state\n",
3539 sta->sta.addr);
3540 WARN_ON(__sta_info_destroy(sta));
3541 mutex_unlock(&sdata->local->sta_mtx);
3542 ret = false;
3543 goto out;
3544 }
3545
3546 mutex_unlock(&sdata->local->sta_mtx);
3547
3548 /*
3549 * Always handle WMM once after association regardless
3550 * of the first value the AP uses. Setting -1 here has
3551 * that effect because the AP values is an unsigned
3552 * 4-bit value.
3553 */
3554 ifmgd->wmm_last_param_set = -1;
3555 ifmgd->mu_edca_last_param_set = -1;
3556
3557 if (ifmgd->flags & IEEE80211_STA_DISABLE_WMM) {
3558 ieee80211_set_wmm_default(sdata, false, false);
3559 } else if (!ieee80211_sta_wmm_params(local, sdata, elems->wmm_param,
3560 elems->wmm_param_len,
3561 elems->mu_edca_param_set)) {
3562 /* still enable QoS since we might have HT/VHT */
3563 ieee80211_set_wmm_default(sdata, false, true);
3564 /* set the disable-WMM flag in this case to disable
3565 * tracking WMM parameter changes in the beacon if
3566 * the parameters weren't actually valid. Doing so
3567 * avoids changing parameters very strangely when
3568 * the AP is going back and forth between valid and
3569 * invalid parameters.
3570 */
3571 ifmgd->flags |= IEEE80211_STA_DISABLE_WMM;
3572 }
3573 changed |= BSS_CHANGED_QOS;
3574
3575 if (elems->max_idle_period_ie) {
3576 bss_conf->max_idle_period =
3577 le16_to_cpu(elems->max_idle_period_ie->max_idle_period);
3578 bss_conf->protected_keep_alive =
3579 !!(elems->max_idle_period_ie->idle_options &
3580 WLAN_IDLE_OPTIONS_PROTECTED_KEEP_ALIVE);
3581 changed |= BSS_CHANGED_KEEP_ALIVE;
3582 } else {
3583 bss_conf->max_idle_period = 0;
3584 bss_conf->protected_keep_alive = false;
3585 }
3586
3587 /* set assoc capability (AID was already set earlier),
3588 * ieee80211_set_associated() will tell the driver */
3589 bss_conf->assoc_capability = capab_info;
3590 ieee80211_set_associated(sdata, cbss, changed);
3591
3592 /*
3593 * If we're using 4-addr mode, let the AP know that we're
3594 * doing so, so that it can create the STA VLAN on its side
3595 */
3596 if (ifmgd->use_4addr)
3597 ieee80211_send_4addr_nullfunc(local, sdata);
3598
3599 /*
3600 * Start timer to probe the connection to the AP now.
3601 * Also start the timer that will detect beacon loss.
3602 */
3603 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
3604 ieee80211_sta_reset_beacon_monitor(sdata);
3605
3606 ret = true;
3607 out:
3608 kfree(bss_ies);
3609 return ret;
3610 }
3611

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (15.62 kB)
.config.gz (54.58 kB)
Download all attachments

2020-07-07 13:49:26

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2] mac80211: avoid bss color setting in non-he mode

Hi Praneesh,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on mac80211-next/master]
[also build test ERROR on mac80211/master v5.8-rc4 next-20200707]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/P-Praneesh/mac80211-avoid-bss-color-setting-in-non-he-mode/20200707-173732
base: https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git master
config: x86_64-allyesconfig (attached as .config)
compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 02946de3802d3bc65bc9f2eb9b8d4969b5a7add8)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All errors (new ones prefixed by >>):

>> net/mac80211/mlme.c:3465:8: error: use of undeclared identifier 'params'
if (!params->he_bss_color.disabled)
^
1 error generated.

vim +/params +3465 net/mac80211/mlme.c

3250
3251 static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
3252 struct cfg80211_bss *cbss,
3253 struct ieee80211_mgmt *mgmt, size_t len,
3254 struct ieee802_11_elems *elems)
3255 {
3256 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3257 struct ieee80211_local *local = sdata->local;
3258 struct ieee80211_supported_band *sband;
3259 struct sta_info *sta;
3260 u16 capab_info, aid;
3261 struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
3262 const struct cfg80211_bss_ies *bss_ies = NULL;
3263 struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
3264 bool is_6ghz = cbss->channel->band == NL80211_BAND_6GHZ;
3265 u32 changed = 0;
3266 int err;
3267 bool ret;
3268
3269 /* AssocResp and ReassocResp have identical structure */
3270
3271 aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
3272 capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
3273
3274 /*
3275 * The 5 MSB of the AID field are reserved
3276 * (802.11-2016 9.4.1.8 AID field)
3277 */
3278 aid &= 0x7ff;
3279
3280 ifmgd->broken_ap = false;
3281
3282 if (aid == 0 || aid > IEEE80211_MAX_AID) {
3283 sdata_info(sdata, "invalid AID value %d (out of range), turn off PS\n",
3284 aid);
3285 aid = 0;
3286 ifmgd->broken_ap = true;
3287 }
3288
3289 if (!elems->supp_rates) {
3290 sdata_info(sdata, "no SuppRates element in AssocResp\n");
3291 return false;
3292 }
3293
3294 sdata->vif.bss_conf.aid = aid;
3295 ifmgd->tdls_chan_switch_prohibited =
3296 elems->ext_capab && elems->ext_capab_len >= 5 &&
3297 (elems->ext_capab[4] & WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED);
3298
3299 /*
3300 * Some APs are erroneously not including some information in their
3301 * (re)association response frames. Try to recover by using the data
3302 * from the beacon or probe response. This seems to afflict mobile
3303 * 2G/3G/4G wifi routers, reported models include the "Onda PN51T",
3304 * "Vodafone PocketWiFi 2", "ZTE MF60" and a similar T-Mobile device.
3305 */
3306 if (!is_6ghz &&
3307 ((assoc_data->wmm && !elems->wmm_param) ||
3308 (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
3309 (!elems->ht_cap_elem || !elems->ht_operation)) ||
3310 (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
3311 (!elems->vht_cap_elem || !elems->vht_operation)))) {
3312 const struct cfg80211_bss_ies *ies;
3313 struct ieee802_11_elems bss_elems;
3314
3315 rcu_read_lock();
3316 ies = rcu_dereference(cbss->ies);
3317 if (ies)
3318 bss_ies = kmemdup(ies, sizeof(*ies) + ies->len,
3319 GFP_ATOMIC);
3320 rcu_read_unlock();
3321 if (!bss_ies)
3322 return false;
3323
3324 ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
3325 false, &bss_elems,
3326 mgmt->bssid,
3327 assoc_data->bss->bssid);
3328 if (assoc_data->wmm &&
3329 !elems->wmm_param && bss_elems.wmm_param) {
3330 elems->wmm_param = bss_elems.wmm_param;
3331 sdata_info(sdata,
3332 "AP bug: WMM param missing from AssocResp\n");
3333 }
3334
3335 /*
3336 * Also check if we requested HT/VHT, otherwise the AP doesn't
3337 * have to include the IEs in the (re)association response.
3338 */
3339 if (!elems->ht_cap_elem && bss_elems.ht_cap_elem &&
3340 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
3341 elems->ht_cap_elem = bss_elems.ht_cap_elem;
3342 sdata_info(sdata,
3343 "AP bug: HT capability missing from AssocResp\n");
3344 }
3345 if (!elems->ht_operation && bss_elems.ht_operation &&
3346 !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
3347 elems->ht_operation = bss_elems.ht_operation;
3348 sdata_info(sdata,
3349 "AP bug: HT operation missing from AssocResp\n");
3350 }
3351 if (!elems->vht_cap_elem && bss_elems.vht_cap_elem &&
3352 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
3353 elems->vht_cap_elem = bss_elems.vht_cap_elem;
3354 sdata_info(sdata,
3355 "AP bug: VHT capa missing from AssocResp\n");
3356 }
3357 if (!elems->vht_operation && bss_elems.vht_operation &&
3358 !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
3359 elems->vht_operation = bss_elems.vht_operation;
3360 sdata_info(sdata,
3361 "AP bug: VHT operation missing from AssocResp\n");
3362 }
3363 }
3364
3365 /*
3366 * We previously checked these in the beacon/probe response, so
3367 * they should be present here. This is just a safety net.
3368 */
3369 if (!is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
3370 (!elems->wmm_param || !elems->ht_cap_elem || !elems->ht_operation)) {
3371 sdata_info(sdata,
3372 "HT AP is missing WMM params or HT capability/operation\n");
3373 ret = false;
3374 goto out;
3375 }
3376
3377 if (!is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
3378 (!elems->vht_cap_elem || !elems->vht_operation)) {
3379 sdata_info(sdata,
3380 "VHT AP is missing VHT capability/operation\n");
3381 ret = false;
3382 goto out;
3383 }
3384
3385 if (is_6ghz && !(ifmgd->flags & IEEE80211_STA_DISABLE_HE) &&
3386 !elems->he_6ghz_capa) {
3387 sdata_info(sdata,
3388 "HE 6 GHz AP is missing HE 6 GHz band capability\n");
3389 ret = false;
3390 goto out;
3391 }
3392
3393 mutex_lock(&sdata->local->sta_mtx);
3394 /*
3395 * station info was already allocated and inserted before
3396 * the association and should be available to us
3397 */
3398 sta = sta_info_get(sdata, cbss->bssid);
3399 if (WARN_ON(!sta)) {
3400 mutex_unlock(&sdata->local->sta_mtx);
3401 ret = false;
3402 goto out;
3403 }
3404
3405 sband = ieee80211_get_sband(sdata);
3406 if (!sband) {
3407 mutex_unlock(&sdata->local->sta_mtx);
3408 ret = false;
3409 goto out;
3410 }
3411
3412 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HE) &&
3413 (!elems->he_cap || !elems->he_operation)) {
3414 mutex_unlock(&sdata->local->sta_mtx);
3415 sdata_info(sdata,
3416 "HE AP is missing HE capability/operation\n");
3417 ret = false;
3418 goto out;
3419 }
3420
3421 /* Set up internal HT/VHT capabilities */
3422 if (elems->ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
3423 ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
3424 elems->ht_cap_elem, sta);
3425
3426 if (elems->vht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT))
3427 ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
3428 elems->vht_cap_elem, sta);
3429
3430 if (elems->he_operation && !(ifmgd->flags & IEEE80211_STA_DISABLE_HE) &&
3431 elems->he_cap) {
3432 ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband,
3433 elems->he_cap,
3434 elems->he_cap_len,
3435 elems->he_6ghz_capa,
3436 sta);
3437
3438 bss_conf->he_support = sta->sta.he_cap.has_he;
3439 if (elems->rsnx && elems->rsnx_len &&
3440 (elems->rsnx[0] & WLAN_RSNX_CAPA_PROTECTED_TWT) &&
3441 wiphy_ext_feature_isset(local->hw.wiphy,
3442 NL80211_EXT_FEATURE_PROTECTED_TWT))
3443 bss_conf->twt_protected = true;
3444 else
3445 bss_conf->twt_protected = false;
3446
3447 changed |= ieee80211_recalc_twt_req(sdata, sta, elems);
3448 } else {
3449 bss_conf->he_support = false;
3450 bss_conf->twt_requester = false;
3451 bss_conf->twt_protected = false;
3452 }
3453
3454 if (bss_conf->he_support) {
3455 bss_conf->he_bss_color.color =
3456 le32_get_bits(elems->he_operation->he_oper_params,
3457 IEEE80211_HE_OPERATION_BSS_COLOR_MASK);
3458 bss_conf->he_bss_color.partial =
3459 le32_get_bits(elems->he_operation->he_oper_params,
3460 IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR);
3461 bss_conf->he_bss_color.disabled =
3462 le32_get_bits(elems->he_operation->he_oper_params,
3463 IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED);
3464
> 3465 if (!params->he_bss_color.disabled)
3466 changed |= BSS_CHANGED_HE_BSS_COLOR;
3467
3468 bss_conf->htc_trig_based_pkt_ext =
3469 le32_get_bits(elems->he_operation->he_oper_params,
3470 IEEE80211_HE_OPERATION_DFLT_PE_DURATION_MASK);
3471 bss_conf->frame_time_rts_th =
3472 le32_get_bits(elems->he_operation->he_oper_params,
3473 IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK);
3474
3475 bss_conf->multi_sta_back_32bit =
3476 sta->sta.he_cap.he_cap_elem.mac_cap_info[2] &
3477 IEEE80211_HE_MAC_CAP2_32BIT_BA_BITMAP;
3478
3479 bss_conf->ack_enabled =
3480 sta->sta.he_cap.he_cap_elem.mac_cap_info[2] &
3481 IEEE80211_HE_MAC_CAP2_ACK_EN;
3482
3483 bss_conf->uora_exists = !!elems->uora_element;
3484 if (elems->uora_element)
3485 bss_conf->uora_ocw_range = elems->uora_element[0];
3486
3487 ieee80211_he_op_ie_to_bss_conf(&sdata->vif, elems->he_operation);
3488 ieee80211_he_spr_ie_to_bss_conf(&sdata->vif, elems->he_spr);
3489 /* TODO: OPEN: what happens if BSS color disable is set? */
3490 }
3491
3492 if (cbss->transmitted_bss) {
3493 bss_conf->nontransmitted = true;
3494 ether_addr_copy(bss_conf->transmitter_bssid,
3495 cbss->transmitted_bss->bssid);
3496 bss_conf->bssid_indicator = cbss->max_bssid_indicator;
3497 bss_conf->bssid_index = cbss->bssid_index;
3498 }
3499
3500 /*
3501 * Some APs, e.g. Netgear WNDR3700, report invalid HT operation data
3502 * in their association response, so ignore that data for our own
3503 * configuration. If it changed since the last beacon, we'll get the
3504 * next beacon and update then.
3505 */
3506
3507 /*
3508 * If an operating mode notification IE is present, override the
3509 * NSS calculation (that would be done in rate_control_rate_init())
3510 * and use the # of streams from that element.
3511 */
3512 if (elems->opmode_notif &&
3513 !(*elems->opmode_notif & IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF)) {
3514 u8 nss;
3515
3516 nss = *elems->opmode_notif & IEEE80211_OPMODE_NOTIF_RX_NSS_MASK;
3517 nss >>= IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
3518 nss += 1;
3519 sta->sta.rx_nss = nss;
3520 }
3521
3522 rate_control_rate_init(sta);
3523
3524 if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) {
3525 set_sta_flag(sta, WLAN_STA_MFP);
3526 sta->sta.mfp = true;
3527 } else {
3528 sta->sta.mfp = false;
3529 }
3530
3531 sta->sta.wme = elems->wmm_param && local->hw.queues >= IEEE80211_NUM_ACS;
3532
3533 err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
3534 if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
3535 err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
3536 if (err) {
3537 sdata_info(sdata,
3538 "failed to move station %pM to desired state\n",
3539 sta->sta.addr);
3540 WARN_ON(__sta_info_destroy(sta));
3541 mutex_unlock(&sdata->local->sta_mtx);
3542 ret = false;
3543 goto out;
3544 }
3545
3546 mutex_unlock(&sdata->local->sta_mtx);
3547
3548 /*
3549 * Always handle WMM once after association regardless
3550 * of the first value the AP uses. Setting -1 here has
3551 * that effect because the AP values is an unsigned
3552 * 4-bit value.
3553 */
3554 ifmgd->wmm_last_param_set = -1;
3555 ifmgd->mu_edca_last_param_set = -1;
3556
3557 if (ifmgd->flags & IEEE80211_STA_DISABLE_WMM) {
3558 ieee80211_set_wmm_default(sdata, false, false);
3559 } else if (!ieee80211_sta_wmm_params(local, sdata, elems->wmm_param,
3560 elems->wmm_param_len,
3561 elems->mu_edca_param_set)) {
3562 /* still enable QoS since we might have HT/VHT */
3563 ieee80211_set_wmm_default(sdata, false, true);
3564 /* set the disable-WMM flag in this case to disable
3565 * tracking WMM parameter changes in the beacon if
3566 * the parameters weren't actually valid. Doing so
3567 * avoids changing parameters very strangely when
3568 * the AP is going back and forth between valid and
3569 * invalid parameters.
3570 */
3571 ifmgd->flags |= IEEE80211_STA_DISABLE_WMM;
3572 }
3573 changed |= BSS_CHANGED_QOS;
3574
3575 if (elems->max_idle_period_ie) {
3576 bss_conf->max_idle_period =
3577 le16_to_cpu(elems->max_idle_period_ie->max_idle_period);
3578 bss_conf->protected_keep_alive =
3579 !!(elems->max_idle_period_ie->idle_options &
3580 WLAN_IDLE_OPTIONS_PROTECTED_KEEP_ALIVE);
3581 changed |= BSS_CHANGED_KEEP_ALIVE;
3582 } else {
3583 bss_conf->max_idle_period = 0;
3584 bss_conf->protected_keep_alive = false;
3585 }
3586
3587 /* set assoc capability (AID was already set earlier),
3588 * ieee80211_set_associated() will tell the driver */
3589 bss_conf->assoc_capability = capab_info;
3590 ieee80211_set_associated(sdata, cbss, changed);
3591
3592 /*
3593 * If we're using 4-addr mode, let the AP know that we're
3594 * doing so, so that it can create the STA VLAN on its side
3595 */
3596 if (ifmgd->use_4addr)
3597 ieee80211_send_4addr_nullfunc(local, sdata);
3598
3599 /*
3600 * Start timer to probe the connection to the AP now.
3601 * Also start the timer that will detect beacon loss.
3602 */
3603 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
3604 ieee80211_sta_reset_beacon_monitor(sdata);
3605
3606 ret = true;
3607 out:
3608 kfree(bss_ies);
3609 return ret;
3610 }
3611

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (15.60 kB)
.config.gz (72.70 kB)
Download all attachments