Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * BSS client mode implementation
0004  * Copyright 2003-2008, Jouni Malinen <j@w1.fi>
0005  * Copyright 2004, Instant802 Networks, Inc.
0006  * Copyright 2005, Devicescape Software, Inc.
0007  * Copyright 2006-2007  Jiri Benc <jbenc@suse.cz>
0008  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
0009  * Copyright 2013-2014  Intel Mobile Communications GmbH
0010  * Copyright (C) 2015 - 2017 Intel Deutschland GmbH
0011  * Copyright (C) 2018 - 2022 Intel Corporation
0012  */
0013 
0014 #include <linux/delay.h>
0015 #include <linux/fips.h>
0016 #include <linux/if_ether.h>
0017 #include <linux/skbuff.h>
0018 #include <linux/if_arp.h>
0019 #include <linux/etherdevice.h>
0020 #include <linux/moduleparam.h>
0021 #include <linux/rtnetlink.h>
0022 #include <linux/crc32.h>
0023 #include <linux/slab.h>
0024 #include <linux/export.h>
0025 #include <net/mac80211.h>
0026 #include <asm/unaligned.h>
0027 
0028 #include "ieee80211_i.h"
0029 #include "driver-ops.h"
0030 #include "rate.h"
0031 #include "led.h"
0032 #include "fils_aead.h"
0033 
0034 #define IEEE80211_AUTH_TIMEOUT      (HZ / 5)
0035 #define IEEE80211_AUTH_TIMEOUT_LONG (HZ / 2)
0036 #define IEEE80211_AUTH_TIMEOUT_SHORT    (HZ / 10)
0037 #define IEEE80211_AUTH_TIMEOUT_SAE  (HZ * 2)
0038 #define IEEE80211_AUTH_MAX_TRIES    3
0039 #define IEEE80211_AUTH_WAIT_ASSOC   (HZ * 5)
0040 #define IEEE80211_AUTH_WAIT_SAE_RETRY   (HZ * 2)
0041 #define IEEE80211_ASSOC_TIMEOUT     (HZ / 5)
0042 #define IEEE80211_ASSOC_TIMEOUT_LONG    (HZ / 2)
0043 #define IEEE80211_ASSOC_TIMEOUT_SHORT   (HZ / 10)
0044 #define IEEE80211_ASSOC_MAX_TRIES   3
0045 
0046 static int max_nullfunc_tries = 2;
0047 module_param(max_nullfunc_tries, int, 0644);
0048 MODULE_PARM_DESC(max_nullfunc_tries,
0049          "Maximum nullfunc tx tries before disconnecting (reason 4).");
0050 
0051 static int max_probe_tries = 5;
0052 module_param(max_probe_tries, int, 0644);
0053 MODULE_PARM_DESC(max_probe_tries,
0054          "Maximum probe tries before disconnecting (reason 4).");
0055 
0056 /*
0057  * Beacon loss timeout is calculated as N frames times the
0058  * advertised beacon interval.  This may need to be somewhat
0059  * higher than what hardware might detect to account for
0060  * delays in the host processing frames. But since we also
0061  * probe on beacon miss before declaring the connection lost
0062  * default to what we want.
0063  */
0064 static int beacon_loss_count = 7;
0065 module_param(beacon_loss_count, int, 0644);
0066 MODULE_PARM_DESC(beacon_loss_count,
0067          "Number of beacon intervals before we decide beacon was lost.");
0068 
0069 /*
0070  * Time the connection can be idle before we probe
0071  * it to see if we can still talk to the AP.
0072  */
0073 #define IEEE80211_CONNECTION_IDLE_TIME  (30 * HZ)
0074 /*
0075  * Time we wait for a probe response after sending
0076  * a probe request because of beacon loss or for
0077  * checking the connection still works.
0078  */
0079 static int probe_wait_ms = 500;
0080 module_param(probe_wait_ms, int, 0644);
0081 MODULE_PARM_DESC(probe_wait_ms,
0082          "Maximum time(ms) to wait for probe response"
0083          " before disconnecting (reason 4).");
0084 
0085 /*
0086  * How many Beacon frames need to have been used in average signal strength
0087  * before starting to indicate signal change events.
0088  */
0089 #define IEEE80211_SIGNAL_AVE_MIN_COUNT  4
0090 
0091 /*
0092  * We can have multiple work items (and connection probing)
0093  * scheduling this timer, but we need to take care to only
0094  * reschedule it when it should fire _earlier_ than it was
0095  * asked for before, or if it's not pending right now. This
0096  * function ensures that. Note that it then is required to
0097  * run this function for all timeouts after the first one
0098  * has happened -- the work that runs from this timer will
0099  * do that.
0100  */
0101 static void run_again(struct ieee80211_sub_if_data *sdata,
0102               unsigned long timeout)
0103 {
0104     sdata_assert_lock(sdata);
0105 
0106     if (!timer_pending(&sdata->u.mgd.timer) ||
0107         time_before(timeout, sdata->u.mgd.timer.expires))
0108         mod_timer(&sdata->u.mgd.timer, timeout);
0109 }
0110 
0111 void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
0112 {
0113     if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)
0114         return;
0115 
0116     if (ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
0117         return;
0118 
0119     mod_timer(&sdata->u.mgd.bcn_mon_timer,
0120           round_jiffies_up(jiffies + sdata->u.mgd.beacon_timeout));
0121 }
0122 
0123 void ieee80211_sta_reset_conn_monitor(struct ieee80211_sub_if_data *sdata)
0124 {
0125     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
0126 
0127     if (unlikely(!ifmgd->associated))
0128         return;
0129 
0130     if (ifmgd->probe_send_count)
0131         ifmgd->probe_send_count = 0;
0132 
0133     if (ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
0134         return;
0135 
0136     mod_timer(&ifmgd->conn_mon_timer,
0137           round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
0138 }
0139 
0140 static int ecw2cw(int ecw)
0141 {
0142     return (1 << ecw) - 1;
0143 }
0144 
0145 static ieee80211_conn_flags_t
0146 ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
0147                  struct ieee80211_link_data *link,
0148                  ieee80211_conn_flags_t conn_flags,
0149                  struct ieee80211_supported_band *sband,
0150                  struct ieee80211_channel *channel,
0151                  u32 vht_cap_info,
0152                  const struct ieee80211_ht_operation *ht_oper,
0153                  const struct ieee80211_vht_operation *vht_oper,
0154                  const struct ieee80211_he_operation *he_oper,
0155                  const struct ieee80211_eht_operation *eht_oper,
0156                  const struct ieee80211_s1g_oper_ie *s1g_oper,
0157                  struct cfg80211_chan_def *chandef, bool tracking)
0158 {
0159     struct cfg80211_chan_def vht_chandef;
0160     struct ieee80211_sta_ht_cap sta_ht_cap;
0161     ieee80211_conn_flags_t ret;
0162     u32 ht_cfreq;
0163 
0164     memset(chandef, 0, sizeof(struct cfg80211_chan_def));
0165     chandef->chan = channel;
0166     chandef->width = NL80211_CHAN_WIDTH_20_NOHT;
0167     chandef->center_freq1 = channel->center_freq;
0168     chandef->freq1_offset = channel->freq_offset;
0169 
0170     if (channel->band == NL80211_BAND_6GHZ) {
0171         if (!ieee80211_chandef_he_6ghz_oper(sdata, he_oper, eht_oper,
0172                             chandef)) {
0173             mlme_dbg(sdata,
0174                  "bad 6 GHz operation, disabling HT/VHT/HE/EHT\n");
0175             ret = IEEE80211_CONN_DISABLE_HT |
0176                   IEEE80211_CONN_DISABLE_VHT |
0177                   IEEE80211_CONN_DISABLE_HE |
0178                   IEEE80211_CONN_DISABLE_EHT;
0179         } else {
0180             ret = 0;
0181         }
0182         vht_chandef = *chandef;
0183         goto out;
0184     } else if (sband->band == NL80211_BAND_S1GHZ) {
0185         if (!ieee80211_chandef_s1g_oper(s1g_oper, chandef)) {
0186             sdata_info(sdata,
0187                    "Missing S1G Operation Element? Trying operating == primary\n");
0188             chandef->width = ieee80211_s1g_channel_width(channel);
0189         }
0190 
0191         ret = IEEE80211_CONN_DISABLE_HT | IEEE80211_CONN_DISABLE_40MHZ |
0192               IEEE80211_CONN_DISABLE_VHT |
0193               IEEE80211_CONN_DISABLE_80P80MHZ |
0194               IEEE80211_CONN_DISABLE_160MHZ;
0195         goto out;
0196     }
0197 
0198     memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap));
0199     ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap);
0200 
0201     if (!ht_oper || !sta_ht_cap.ht_supported) {
0202         mlme_dbg(sdata, "HT operation missing / HT not supported\n");
0203         ret = IEEE80211_CONN_DISABLE_HT |
0204               IEEE80211_CONN_DISABLE_VHT |
0205               IEEE80211_CONN_DISABLE_HE |
0206               IEEE80211_CONN_DISABLE_EHT;
0207         goto out;
0208     }
0209 
0210     chandef->width = NL80211_CHAN_WIDTH_20;
0211 
0212     ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan,
0213                           channel->band);
0214     /* check that channel matches the right operating channel */
0215     if (!tracking && channel->center_freq != ht_cfreq) {
0216         /*
0217          * It's possible that some APs are confused here;
0218          * Netgear WNDR3700 sometimes reports 4 higher than
0219          * the actual channel in association responses, but
0220          * since we look at probe response/beacon data here
0221          * it should be OK.
0222          */
0223         sdata_info(sdata,
0224                "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n",
0225                channel->center_freq, ht_cfreq,
0226                ht_oper->primary_chan, channel->band);
0227         ret = IEEE80211_CONN_DISABLE_HT |
0228               IEEE80211_CONN_DISABLE_VHT |
0229               IEEE80211_CONN_DISABLE_HE |
0230               IEEE80211_CONN_DISABLE_EHT;
0231         goto out;
0232     }
0233 
0234     /* check 40 MHz support, if we have it */
0235     if (sta_ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
0236         ieee80211_chandef_ht_oper(ht_oper, chandef);
0237     } else {
0238         mlme_dbg(sdata, "40 MHz not supported\n");
0239         /* 40 MHz (and 80 MHz) must be supported for VHT */
0240         ret = IEEE80211_CONN_DISABLE_VHT;
0241         /* also mark 40 MHz disabled */
0242         ret |= IEEE80211_CONN_DISABLE_40MHZ;
0243         goto out;
0244     }
0245 
0246     if (!vht_oper || !sband->vht_cap.vht_supported) {
0247         mlme_dbg(sdata, "VHT operation missing / VHT not supported\n");
0248         ret = IEEE80211_CONN_DISABLE_VHT;
0249         goto out;
0250     }
0251 
0252     vht_chandef = *chandef;
0253     if (!(conn_flags & IEEE80211_CONN_DISABLE_HE) &&
0254         he_oper &&
0255         (le32_to_cpu(he_oper->he_oper_params) &
0256          IEEE80211_HE_OPERATION_VHT_OPER_INFO)) {
0257         struct ieee80211_vht_operation he_oper_vht_cap;
0258 
0259         /*
0260          * Set only first 3 bytes (other 2 aren't used in
0261          * ieee80211_chandef_vht_oper() anyway)
0262          */
0263         memcpy(&he_oper_vht_cap, he_oper->optional, 3);
0264         he_oper_vht_cap.basic_mcs_set = cpu_to_le16(0);
0265 
0266         if (!ieee80211_chandef_vht_oper(&sdata->local->hw, vht_cap_info,
0267                         &he_oper_vht_cap, ht_oper,
0268                         &vht_chandef)) {
0269             if (!(conn_flags & IEEE80211_CONN_DISABLE_HE))
0270                 sdata_info(sdata,
0271                        "HE AP VHT information is invalid, disabling HE\n");
0272             ret = IEEE80211_CONN_DISABLE_HE | IEEE80211_CONN_DISABLE_EHT;
0273             goto out;
0274         }
0275     } else if (!ieee80211_chandef_vht_oper(&sdata->local->hw,
0276                            vht_cap_info,
0277                            vht_oper, ht_oper,
0278                            &vht_chandef)) {
0279         if (!(conn_flags & IEEE80211_CONN_DISABLE_VHT))
0280             sdata_info(sdata,
0281                    "AP VHT information is invalid, disabling VHT\n");
0282         ret = IEEE80211_CONN_DISABLE_VHT;
0283         goto out;
0284     }
0285 
0286     if (!cfg80211_chandef_valid(&vht_chandef)) {
0287         if (!(conn_flags & IEEE80211_CONN_DISABLE_VHT))
0288             sdata_info(sdata,
0289                    "AP VHT information is invalid, disabling VHT\n");
0290         ret = IEEE80211_CONN_DISABLE_VHT;
0291         goto out;
0292     }
0293 
0294     if (cfg80211_chandef_identical(chandef, &vht_chandef)) {
0295         ret = 0;
0296         goto out;
0297     }
0298 
0299     if (!cfg80211_chandef_compatible(chandef, &vht_chandef)) {
0300         if (!(conn_flags & IEEE80211_CONN_DISABLE_VHT))
0301             sdata_info(sdata,
0302                    "AP VHT information doesn't match HT, disabling VHT\n");
0303         ret = IEEE80211_CONN_DISABLE_VHT;
0304         goto out;
0305     }
0306 
0307     *chandef = vht_chandef;
0308 
0309     /*
0310      * handle the case that the EHT operation indicates that it holds EHT
0311      * operation information (in case that the channel width differs from
0312      * the channel width reported in HT/VHT/HE).
0313      */
0314     if (eht_oper && (eht_oper->params & IEEE80211_EHT_OPER_INFO_PRESENT)) {
0315         struct cfg80211_chan_def eht_chandef = *chandef;
0316 
0317         ieee80211_chandef_eht_oper(sdata, eht_oper,
0318                        eht_chandef.width ==
0319                        NL80211_CHAN_WIDTH_160,
0320                        false, &eht_chandef);
0321 
0322         if (!cfg80211_chandef_valid(&eht_chandef)) {
0323             if (!(conn_flags & IEEE80211_CONN_DISABLE_EHT))
0324                 sdata_info(sdata,
0325                        "AP EHT information is invalid, disabling EHT\n");
0326             ret = IEEE80211_CONN_DISABLE_EHT;
0327             goto out;
0328         }
0329 
0330         if (!cfg80211_chandef_compatible(chandef, &eht_chandef)) {
0331             if (!(conn_flags & IEEE80211_CONN_DISABLE_EHT))
0332                 sdata_info(sdata,
0333                        "AP EHT information is incompatible, disabling EHT\n");
0334             ret = IEEE80211_CONN_DISABLE_EHT;
0335             goto out;
0336         }
0337 
0338         *chandef = eht_chandef;
0339     }
0340 
0341     ret = 0;
0342 
0343 out:
0344     /*
0345      * When tracking the current AP, don't do any further checks if the
0346      * new chandef is identical to the one we're currently using for the
0347      * connection. This keeps us from playing ping-pong with regulatory,
0348      * without it the following can happen (for example):
0349      *  - connect to an AP with 80 MHz, world regdom allows 80 MHz
0350      *  - AP advertises regdom US
0351      *  - CRDA loads regdom US with 80 MHz prohibited (old database)
0352      *  - the code below detects an unsupported channel, downgrades, and
0353      *    we disconnect from the AP in the caller
0354      *  - disconnect causes CRDA to reload world regdomain and the game
0355      *    starts anew.
0356      * (see https://bugzilla.kernel.org/show_bug.cgi?id=70881)
0357      *
0358      * It seems possible that there are still scenarios with CSA or real
0359      * bandwidth changes where a this could happen, but those cases are
0360      * less common and wouldn't completely prevent using the AP.
0361      */
0362     if (tracking &&
0363         cfg80211_chandef_identical(chandef, &link->conf->chandef))
0364         return ret;
0365 
0366     /* don't print the message below for VHT mismatch if VHT is disabled */
0367     if (ret & IEEE80211_CONN_DISABLE_VHT)
0368         vht_chandef = *chandef;
0369 
0370     /*
0371      * Ignore the DISABLED flag when we're already connected and only
0372      * tracking the APs beacon for bandwidth changes - otherwise we
0373      * might get disconnected here if we connect to an AP, update our
0374      * regulatory information based on the AP's country IE and the
0375      * information we have is wrong/outdated and disables the channel
0376      * that we're actually using for the connection to the AP.
0377      */
0378     while (!cfg80211_chandef_usable(sdata->local->hw.wiphy, chandef,
0379                     tracking ? 0 :
0380                            IEEE80211_CHAN_DISABLED)) {
0381         if (WARN_ON(chandef->width == NL80211_CHAN_WIDTH_20_NOHT)) {
0382             ret = IEEE80211_CONN_DISABLE_HT |
0383                   IEEE80211_CONN_DISABLE_VHT |
0384                   IEEE80211_CONN_DISABLE_HE |
0385                   IEEE80211_CONN_DISABLE_EHT;
0386             break;
0387         }
0388 
0389         ret |= ieee80211_chandef_downgrade(chandef);
0390     }
0391 
0392     if (!he_oper || !cfg80211_chandef_usable(sdata->wdev.wiphy, chandef,
0393                          IEEE80211_CHAN_NO_HE))
0394         ret |= IEEE80211_CONN_DISABLE_HE | IEEE80211_CONN_DISABLE_EHT;
0395 
0396     if (!eht_oper || !cfg80211_chandef_usable(sdata->wdev.wiphy, chandef,
0397                           IEEE80211_CHAN_NO_EHT))
0398         ret |= IEEE80211_CONN_DISABLE_EHT;
0399 
0400     if (chandef->width != vht_chandef.width && !tracking)
0401         sdata_info(sdata,
0402                "capabilities/regulatory prevented using AP HT/VHT configuration, downgraded\n");
0403 
0404     WARN_ON_ONCE(!cfg80211_chandef_valid(chandef));
0405     return ret;
0406 }
0407 
0408 static int ieee80211_config_bw(struct ieee80211_link_data *link,
0409                    const struct ieee80211_ht_cap *ht_cap,
0410                    const struct ieee80211_vht_cap *vht_cap,
0411                    const struct ieee80211_ht_operation *ht_oper,
0412                    const struct ieee80211_vht_operation *vht_oper,
0413                    const struct ieee80211_he_operation *he_oper,
0414                    const struct ieee80211_eht_operation *eht_oper,
0415                    const struct ieee80211_s1g_oper_ie *s1g_oper,
0416                    const u8 *bssid, u32 *changed)
0417 {
0418     struct ieee80211_sub_if_data *sdata = link->sdata;
0419     struct ieee80211_local *local = sdata->local;
0420     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
0421     struct ieee80211_channel *chan = link->conf->chandef.chan;
0422     struct ieee80211_supported_band *sband =
0423         local->hw.wiphy->bands[chan->band];
0424     struct cfg80211_chan_def chandef;
0425     u16 ht_opmode;
0426     ieee80211_conn_flags_t flags;
0427     u32 vht_cap_info = 0;
0428     int ret;
0429 
0430     /* if HT was/is disabled, don't track any bandwidth changes */
0431     if (link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HT || !ht_oper)
0432         return 0;
0433 
0434     /* don't check VHT if we associated as non-VHT station */
0435     if (link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT)
0436         vht_oper = NULL;
0437 
0438     /* don't check HE if we associated as non-HE station */
0439     if (link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HE ||
0440         !ieee80211_get_he_iftype_cap(sband,
0441                      ieee80211_vif_type_p2p(&sdata->vif))) {
0442         he_oper = NULL;
0443         eht_oper = NULL;
0444     }
0445 
0446     /* don't check EHT if we associated as non-EHT station */
0447     if (link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_EHT ||
0448         !ieee80211_get_eht_iftype_cap(sband,
0449                      ieee80211_vif_type_p2p(&sdata->vif)))
0450         eht_oper = NULL;
0451 
0452     /*
0453      * if bss configuration changed store the new one -
0454      * this may be applicable even if channel is identical
0455      */
0456     ht_opmode = le16_to_cpu(ht_oper->operation_mode);
0457     if (link->conf->ht_operation_mode != ht_opmode) {
0458         *changed |= BSS_CHANGED_HT;
0459         link->conf->ht_operation_mode = ht_opmode;
0460     }
0461 
0462     if (vht_cap)
0463         vht_cap_info = le32_to_cpu(vht_cap->vht_cap_info);
0464 
0465     /* calculate new channel (type) based on HT/VHT/HE operation IEs */
0466     flags = ieee80211_determine_chantype(sdata, link,
0467                          link->u.mgd.conn_flags,
0468                          sband, chan, vht_cap_info,
0469                          ht_oper, vht_oper,
0470                          he_oper, eht_oper,
0471                          s1g_oper, &chandef, true);
0472 
0473     /*
0474      * Downgrade the new channel if we associated with restricted
0475      * capabilities. For example, if we associated as a 20 MHz STA
0476      * to a 40 MHz AP (due to regulatory, capabilities or config
0477      * reasons) then switching to a 40 MHz channel now won't do us
0478      * any good -- we couldn't use it with the AP.
0479      */
0480     if (link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_80P80MHZ &&
0481         chandef.width == NL80211_CHAN_WIDTH_80P80)
0482         flags |= ieee80211_chandef_downgrade(&chandef);
0483     if (link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_160MHZ &&
0484         chandef.width == NL80211_CHAN_WIDTH_160)
0485         flags |= ieee80211_chandef_downgrade(&chandef);
0486     if (link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_40MHZ &&
0487         chandef.width > NL80211_CHAN_WIDTH_20)
0488         flags |= ieee80211_chandef_downgrade(&chandef);
0489 
0490     if (cfg80211_chandef_identical(&chandef, &link->conf->chandef))
0491         return 0;
0492 
0493     link_info(link,
0494           "AP %pM changed bandwidth, new config is %d.%03d MHz, width %d (%d.%03d/%d MHz)\n",
0495           link->u.mgd.bssid, chandef.chan->center_freq,
0496           chandef.chan->freq_offset, chandef.width,
0497           chandef.center_freq1, chandef.freq1_offset,
0498           chandef.center_freq2);
0499 
0500     if (flags != (link->u.mgd.conn_flags &
0501                 (IEEE80211_CONN_DISABLE_HT |
0502                  IEEE80211_CONN_DISABLE_VHT |
0503                  IEEE80211_CONN_DISABLE_HE |
0504                  IEEE80211_CONN_DISABLE_EHT |
0505                  IEEE80211_CONN_DISABLE_40MHZ |
0506                  IEEE80211_CONN_DISABLE_80P80MHZ |
0507                  IEEE80211_CONN_DISABLE_160MHZ |
0508                  IEEE80211_CONN_DISABLE_320MHZ)) ||
0509         !cfg80211_chandef_valid(&chandef)) {
0510         sdata_info(sdata,
0511                "AP %pM changed caps/bw in a way we can't support (0x%x/0x%x) - disconnect\n",
0512                link->u.mgd.bssid, flags, ifmgd->flags);
0513         return -EINVAL;
0514     }
0515 
0516     ret = ieee80211_link_change_bandwidth(link, &chandef, changed);
0517 
0518     if (ret) {
0519         sdata_info(sdata,
0520                "AP %pM changed bandwidth to incompatible one - disconnect\n",
0521                link->u.mgd.bssid);
0522         return ret;
0523     }
0524 
0525     return 0;
0526 }
0527 
0528 /* frame sending functions */
0529 
0530 static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata,
0531                 struct sk_buff *skb, u8 ap_ht_param,
0532                 struct ieee80211_supported_band *sband,
0533                 struct ieee80211_channel *channel,
0534                 enum ieee80211_smps_mode smps,
0535                 ieee80211_conn_flags_t conn_flags)
0536 {
0537     u8 *pos;
0538     u32 flags = channel->flags;
0539     u16 cap;
0540     struct ieee80211_sta_ht_cap ht_cap;
0541 
0542     BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap));
0543 
0544     memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
0545     ieee80211_apply_htcap_overrides(sdata, &ht_cap);
0546 
0547     /* determine capability flags */
0548     cap = ht_cap.cap;
0549 
0550     switch (ap_ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) {
0551     case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
0552         if (flags & IEEE80211_CHAN_NO_HT40PLUS) {
0553             cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
0554             cap &= ~IEEE80211_HT_CAP_SGI_40;
0555         }
0556         break;
0557     case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
0558         if (flags & IEEE80211_CHAN_NO_HT40MINUS) {
0559             cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
0560             cap &= ~IEEE80211_HT_CAP_SGI_40;
0561         }
0562         break;
0563     }
0564 
0565     /*
0566      * If 40 MHz was disabled associate as though we weren't
0567      * capable of 40 MHz -- some broken APs will never fall
0568      * back to trying to transmit in 20 MHz.
0569      */
0570     if (conn_flags & IEEE80211_CONN_DISABLE_40MHZ) {
0571         cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
0572         cap &= ~IEEE80211_HT_CAP_SGI_40;
0573     }
0574 
0575     /* set SM PS mode properly */
0576     cap &= ~IEEE80211_HT_CAP_SM_PS;
0577     switch (smps) {
0578     case IEEE80211_SMPS_AUTOMATIC:
0579     case IEEE80211_SMPS_NUM_MODES:
0580         WARN_ON(1);
0581         fallthrough;
0582     case IEEE80211_SMPS_OFF:
0583         cap |= WLAN_HT_CAP_SM_PS_DISABLED <<
0584             IEEE80211_HT_CAP_SM_PS_SHIFT;
0585         break;
0586     case IEEE80211_SMPS_STATIC:
0587         cap |= WLAN_HT_CAP_SM_PS_STATIC <<
0588             IEEE80211_HT_CAP_SM_PS_SHIFT;
0589         break;
0590     case IEEE80211_SMPS_DYNAMIC:
0591         cap |= WLAN_HT_CAP_SM_PS_DYNAMIC <<
0592             IEEE80211_HT_CAP_SM_PS_SHIFT;
0593         break;
0594     }
0595 
0596     /* reserve and fill IE */
0597     pos = skb_put(skb, sizeof(struct ieee80211_ht_cap) + 2);
0598     ieee80211_ie_build_ht_cap(pos, &ht_cap, cap);
0599 }
0600 
0601 /* This function determines vht capability flags for the association
0602  * and builds the IE.
0603  * Note - the function returns true to own the MU-MIMO capability
0604  */
0605 static bool ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata,
0606                  struct sk_buff *skb,
0607                  struct ieee80211_supported_band *sband,
0608                  struct ieee80211_vht_cap *ap_vht_cap,
0609                  ieee80211_conn_flags_t conn_flags)
0610 {
0611     struct ieee80211_local *local = sdata->local;
0612     u8 *pos;
0613     u32 cap;
0614     struct ieee80211_sta_vht_cap vht_cap;
0615     u32 mask, ap_bf_sts, our_bf_sts;
0616     bool mu_mimo_owner = false;
0617 
0618     BUILD_BUG_ON(sizeof(vht_cap) != sizeof(sband->vht_cap));
0619 
0620     memcpy(&vht_cap, &sband->vht_cap, sizeof(vht_cap));
0621     ieee80211_apply_vhtcap_overrides(sdata, &vht_cap);
0622 
0623     /* determine capability flags */
0624     cap = vht_cap.cap;
0625 
0626     if (conn_flags & IEEE80211_CONN_DISABLE_80P80MHZ) {
0627         u32 bw = cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
0628 
0629         cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
0630         if (bw == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ ||
0631             bw == IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ)
0632             cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
0633     }
0634 
0635     if (conn_flags & IEEE80211_CONN_DISABLE_160MHZ) {
0636         cap &= ~IEEE80211_VHT_CAP_SHORT_GI_160;
0637         cap &= ~IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK;
0638     }
0639 
0640     /*
0641      * Some APs apparently get confused if our capabilities are better
0642      * than theirs, so restrict what we advertise in the assoc request.
0643      */
0644     if (!(ap_vht_cap->vht_cap_info &
0645             cpu_to_le32(IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE)))
0646         cap &= ~(IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
0647              IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE);
0648     else if (!(ap_vht_cap->vht_cap_info &
0649             cpu_to_le32(IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)))
0650         cap &= ~IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
0651 
0652     /*
0653      * If some other vif is using the MU-MIMO capability we cannot associate
0654      * using MU-MIMO - this will lead to contradictions in the group-id
0655      * mechanism.
0656      * Ownership is defined since association request, in order to avoid
0657      * simultaneous associations with MU-MIMO.
0658      */
0659     if (cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE) {
0660         bool disable_mu_mimo = false;
0661         struct ieee80211_sub_if_data *other;
0662 
0663         list_for_each_entry_rcu(other, &local->interfaces, list) {
0664             if (other->vif.bss_conf.mu_mimo_owner) {
0665                 disable_mu_mimo = true;
0666                 break;
0667             }
0668         }
0669         if (disable_mu_mimo)
0670             cap &= ~IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
0671         else
0672             mu_mimo_owner = true;
0673     }
0674 
0675     mask = IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK;
0676 
0677     ap_bf_sts = le32_to_cpu(ap_vht_cap->vht_cap_info) & mask;
0678     our_bf_sts = cap & mask;
0679 
0680     if (ap_bf_sts < our_bf_sts) {
0681         cap &= ~mask;
0682         cap |= ap_bf_sts;
0683     }
0684 
0685     /* reserve and fill IE */
0686     pos = skb_put(skb, sizeof(struct ieee80211_vht_cap) + 2);
0687     ieee80211_ie_build_vht_cap(pos, &vht_cap, cap);
0688 
0689     return mu_mimo_owner;
0690 }
0691 
0692 /* This function determines HE capability flags for the association
0693  * and builds the IE.
0694  */
0695 static void ieee80211_add_he_ie(struct ieee80211_sub_if_data *sdata,
0696                 struct sk_buff *skb,
0697                 struct ieee80211_supported_band *sband,
0698                 ieee80211_conn_flags_t conn_flags)
0699 {
0700     u8 *pos, *pre_he_pos;
0701     const struct ieee80211_sta_he_cap *he_cap;
0702     u8 he_cap_size;
0703 
0704     he_cap = ieee80211_get_he_iftype_cap(sband,
0705                          ieee80211_vif_type_p2p(&sdata->vif));
0706     if (WARN_ON(!he_cap))
0707         return;
0708 
0709     /* get a max size estimate */
0710     he_cap_size =
0711         2 + 1 + sizeof(he_cap->he_cap_elem) +
0712         ieee80211_he_mcs_nss_size(&he_cap->he_cap_elem) +
0713         ieee80211_he_ppe_size(he_cap->ppe_thres[0],
0714                       he_cap->he_cap_elem.phy_cap_info);
0715     pos = skb_put(skb, he_cap_size);
0716     pre_he_pos = pos;
0717     pos = ieee80211_ie_build_he_cap(conn_flags,
0718                     pos, he_cap, pos + he_cap_size);
0719     /* trim excess if any */
0720     skb_trim(skb, skb->len - (pre_he_pos + he_cap_size - pos));
0721 
0722     ieee80211_ie_build_he_6ghz_cap(sdata, skb);
0723 }
0724 
0725 static void ieee80211_add_eht_ie(struct ieee80211_sub_if_data *sdata,
0726                  struct sk_buff *skb,
0727                  struct ieee80211_supported_band *sband)
0728 {
0729     u8 *pos;
0730     const struct ieee80211_sta_he_cap *he_cap;
0731     const struct ieee80211_sta_eht_cap *eht_cap;
0732     u8 eht_cap_size;
0733 
0734     he_cap = ieee80211_get_he_iftype_cap(sband,
0735                          ieee80211_vif_type_p2p(&sdata->vif));
0736     eht_cap = ieee80211_get_eht_iftype_cap(sband,
0737                            ieee80211_vif_type_p2p(&sdata->vif));
0738 
0739     /*
0740      * EHT capabilities element is only added if the HE capabilities element
0741      * was added so assume that 'he_cap' is valid and don't check it.
0742      */
0743     if (WARN_ON(!he_cap || !eht_cap))
0744         return;
0745 
0746     eht_cap_size =
0747         2 + 1 + sizeof(eht_cap->eht_cap_elem) +
0748         ieee80211_eht_mcs_nss_size(&he_cap->he_cap_elem,
0749                        &eht_cap->eht_cap_elem) +
0750         ieee80211_eht_ppe_size(eht_cap->eht_ppe_thres[0],
0751                        eht_cap->eht_cap_elem.phy_cap_info);
0752     pos = skb_put(skb, eht_cap_size);
0753     ieee80211_ie_build_eht_cap(pos, he_cap, eht_cap, pos + eht_cap_size);
0754 }
0755 
0756 static void ieee80211_assoc_add_rates(struct sk_buff *skb,
0757                       enum nl80211_chan_width width,
0758                       struct ieee80211_supported_band *sband,
0759                       struct ieee80211_mgd_assoc_data *assoc_data)
0760 {
0761     unsigned int shift = ieee80211_chanwidth_get_shift(width);
0762     unsigned int rates_len, supp_rates_len;
0763     u32 rates = 0;
0764     int i, count;
0765     u8 *pos;
0766 
0767     if (assoc_data->supp_rates_len) {
0768         /*
0769          * Get all rates supported by the device and the AP as
0770          * some APs don't like getting a superset of their rates
0771          * in the association request (e.g. D-Link DAP 1353 in
0772          * b-only mode)...
0773          */
0774         rates_len = ieee80211_parse_bitrates(width, sband,
0775                              assoc_data->supp_rates,
0776                              assoc_data->supp_rates_len,
0777                              &rates);
0778     } else {
0779         /*
0780          * In case AP not provide any supported rates information
0781          * before association, we send information element(s) with
0782          * all rates that we support.
0783          */
0784         rates_len = sband->n_bitrates;
0785         for (i = 0; i < sband->n_bitrates; i++)
0786             rates |= BIT(i);
0787     }
0788 
0789     supp_rates_len = rates_len;
0790     if (supp_rates_len > 8)
0791         supp_rates_len = 8;
0792 
0793     pos = skb_put(skb, supp_rates_len + 2);
0794     *pos++ = WLAN_EID_SUPP_RATES;
0795     *pos++ = supp_rates_len;
0796 
0797     count = 0;
0798     for (i = 0; i < sband->n_bitrates; i++) {
0799         if (BIT(i) & rates) {
0800             int rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
0801                         5 * (1 << shift));
0802             *pos++ = (u8)rate;
0803             if (++count == 8)
0804                 break;
0805         }
0806     }
0807 
0808     if (rates_len > count) {
0809         pos = skb_put(skb, rates_len - count + 2);
0810         *pos++ = WLAN_EID_EXT_SUPP_RATES;
0811         *pos++ = rates_len - count;
0812 
0813         for (i++; i < sband->n_bitrates; i++) {
0814             if (BIT(i) & rates) {
0815                 int rate;
0816 
0817                 rate = DIV_ROUND_UP(sband->bitrates[i].bitrate,
0818                             5 * (1 << shift));
0819                 *pos++ = (u8)rate;
0820             }
0821         }
0822     }
0823 }
0824 
0825 static size_t ieee80211_add_before_ht_elems(struct sk_buff *skb,
0826                         const u8 *elems,
0827                         size_t elems_len,
0828                         size_t offset)
0829 {
0830     size_t noffset;
0831 
0832     static const u8 before_ht[] = {
0833         WLAN_EID_SSID,
0834         WLAN_EID_SUPP_RATES,
0835         WLAN_EID_EXT_SUPP_RATES,
0836         WLAN_EID_PWR_CAPABILITY,
0837         WLAN_EID_SUPPORTED_CHANNELS,
0838         WLAN_EID_RSN,
0839         WLAN_EID_QOS_CAPA,
0840         WLAN_EID_RRM_ENABLED_CAPABILITIES,
0841         WLAN_EID_MOBILITY_DOMAIN,
0842         WLAN_EID_FAST_BSS_TRANSITION,   /* reassoc only */
0843         WLAN_EID_RIC_DATA,      /* reassoc only */
0844         WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
0845     };
0846     static const u8 after_ric[] = {
0847         WLAN_EID_SUPPORTED_REGULATORY_CLASSES,
0848         WLAN_EID_HT_CAPABILITY,
0849         WLAN_EID_BSS_COEX_2040,
0850         /* luckily this is almost always there */
0851         WLAN_EID_EXT_CAPABILITY,
0852         WLAN_EID_QOS_TRAFFIC_CAPA,
0853         WLAN_EID_TIM_BCAST_REQ,
0854         WLAN_EID_INTERWORKING,
0855         /* 60 GHz (Multi-band, DMG, MMS) can't happen */
0856         WLAN_EID_VHT_CAPABILITY,
0857         WLAN_EID_OPMODE_NOTIF,
0858     };
0859 
0860     if (!elems_len)
0861         return offset;
0862 
0863     noffset = ieee80211_ie_split_ric(elems, elems_len,
0864                      before_ht,
0865                      ARRAY_SIZE(before_ht),
0866                      after_ric,
0867                      ARRAY_SIZE(after_ric),
0868                      offset);
0869     skb_put_data(skb, elems + offset, noffset - offset);
0870 
0871     return noffset;
0872 }
0873 
0874 static size_t ieee80211_add_before_vht_elems(struct sk_buff *skb,
0875                          const u8 *elems,
0876                          size_t elems_len,
0877                          size_t offset)
0878 {
0879     static const u8 before_vht[] = {
0880         /*
0881          * no need to list the ones split off before HT
0882          * or generated here
0883          */
0884         WLAN_EID_BSS_COEX_2040,
0885         WLAN_EID_EXT_CAPABILITY,
0886         WLAN_EID_QOS_TRAFFIC_CAPA,
0887         WLAN_EID_TIM_BCAST_REQ,
0888         WLAN_EID_INTERWORKING,
0889         /* 60 GHz (Multi-band, DMG, MMS) can't happen */
0890     };
0891     size_t noffset;
0892 
0893     if (!elems_len)
0894         return offset;
0895 
0896     /* RIC already taken care of in ieee80211_add_before_ht_elems() */
0897     noffset = ieee80211_ie_split(elems, elems_len,
0898                      before_vht, ARRAY_SIZE(before_vht),
0899                      offset);
0900     skb_put_data(skb, elems + offset, noffset - offset);
0901 
0902     return noffset;
0903 }
0904 
0905 static size_t ieee80211_add_before_he_elems(struct sk_buff *skb,
0906                         const u8 *elems,
0907                         size_t elems_len,
0908                         size_t offset)
0909 {
0910     static const u8 before_he[] = {
0911         /*
0912          * no need to list the ones split off before VHT
0913          * or generated here
0914          */
0915         WLAN_EID_OPMODE_NOTIF,
0916         WLAN_EID_EXTENSION, WLAN_EID_EXT_FUTURE_CHAN_GUIDANCE,
0917         /* 11ai elements */
0918         WLAN_EID_EXTENSION, WLAN_EID_EXT_FILS_SESSION,
0919         WLAN_EID_EXTENSION, WLAN_EID_EXT_FILS_PUBLIC_KEY,
0920         WLAN_EID_EXTENSION, WLAN_EID_EXT_FILS_KEY_CONFIRM,
0921         WLAN_EID_EXTENSION, WLAN_EID_EXT_FILS_HLP_CONTAINER,
0922         WLAN_EID_EXTENSION, WLAN_EID_EXT_FILS_IP_ADDR_ASSIGN,
0923         /* TODO: add 11ah/11aj/11ak elements */
0924     };
0925     size_t noffset;
0926 
0927     if (!elems_len)
0928         return offset;
0929 
0930     /* RIC already taken care of in ieee80211_add_before_ht_elems() */
0931     noffset = ieee80211_ie_split(elems, elems_len,
0932                      before_he, ARRAY_SIZE(before_he),
0933                      offset);
0934     skb_put_data(skb, elems + offset, noffset - offset);
0935 
0936     return noffset;
0937 }
0938 
0939 #define PRESENT_ELEMS_MAX   8
0940 #define PRESENT_ELEM_EXT_OFFS   0x100
0941 
0942 static void ieee80211_assoc_add_ml_elem(struct ieee80211_sub_if_data *sdata,
0943                     struct sk_buff *skb, u16 capab,
0944                     const struct element *ext_capa,
0945                     const u16 *present_elems);
0946 
0947 static size_t ieee80211_assoc_link_elems(struct ieee80211_sub_if_data *sdata,
0948                      struct sk_buff *skb, u16 *capab,
0949                      const struct element *ext_capa,
0950                      const u8 *extra_elems,
0951                      size_t extra_elems_len,
0952                      unsigned int link_id,
0953                      struct ieee80211_link_data *link,
0954                      u16 *present_elems)
0955 {
0956     enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif);
0957     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
0958     struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
0959     struct cfg80211_bss *cbss = assoc_data->link[link_id].bss;
0960     struct ieee80211_channel *chan = cbss->channel;
0961     const struct ieee80211_sband_iftype_data *iftd;
0962     struct ieee80211_local *local = sdata->local;
0963     struct ieee80211_supported_band *sband;
0964     enum nl80211_chan_width width = NL80211_CHAN_WIDTH_20;
0965     struct ieee80211_chanctx_conf *chanctx_conf;
0966     enum ieee80211_smps_mode smps_mode;
0967     u16 orig_capab = *capab;
0968     size_t offset = 0;
0969     int present_elems_len = 0;
0970     u8 *pos;
0971     int i;
0972 
0973 #define ADD_PRESENT_ELEM(id) do {                   \
0974     /* need a last for termination - we use 0 == SSID */        \
0975     if (!WARN_ON(present_elems_len >= PRESENT_ELEMS_MAX - 1))   \
0976         present_elems[present_elems_len++] = (id);      \
0977 } while (0)
0978 #define ADD_PRESENT_EXT_ELEM(id) ADD_PRESENT_ELEM(PRESENT_ELEM_EXT_OFFS | (id))
0979 
0980     if (link)
0981         smps_mode = link->smps_mode;
0982     else if (sdata->u.mgd.powersave)
0983         smps_mode = IEEE80211_SMPS_DYNAMIC;
0984     else
0985         smps_mode = IEEE80211_SMPS_OFF;
0986 
0987     if (link) {
0988         /*
0989          * 5/10 MHz scenarios are only viable without MLO, in which
0990          * case this pointer should be used ... All of this is a bit
0991          * unclear though, not sure this even works at all.
0992          */
0993         rcu_read_lock();
0994         chanctx_conf = rcu_dereference(link->conf->chanctx_conf);
0995         if (chanctx_conf)
0996             width = chanctx_conf->def.width;
0997         rcu_read_unlock();
0998     }
0999 
1000     sband = local->hw.wiphy->bands[chan->band];
1001     iftd = ieee80211_get_sband_iftype_data(sband, iftype);
1002 
1003     if (sband->band == NL80211_BAND_2GHZ) {
1004         *capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME;
1005         *capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
1006     }
1007 
1008     if ((cbss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
1009         ieee80211_hw_check(&local->hw, SPECTRUM_MGMT))
1010         *capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
1011 
1012     if (sband->band != NL80211_BAND_S1GHZ)
1013         ieee80211_assoc_add_rates(skb, width, sband, assoc_data);
1014 
1015     if (*capab & WLAN_CAPABILITY_SPECTRUM_MGMT ||
1016         *capab & WLAN_CAPABILITY_RADIO_MEASURE) {
1017         struct cfg80211_chan_def chandef = {
1018             .width = width,
1019             .chan = chan,
1020         };
1021 
1022         pos = skb_put(skb, 4);
1023         *pos++ = WLAN_EID_PWR_CAPABILITY;
1024         *pos++ = 2;
1025         *pos++ = 0; /* min tx power */
1026          /* max tx power */
1027         *pos++ = ieee80211_chandef_max_power(&chandef);
1028         ADD_PRESENT_ELEM(WLAN_EID_PWR_CAPABILITY);
1029     }
1030 
1031     /*
1032      * Per spec, we shouldn't include the list of channels if we advertise
1033      * support for extended channel switching, but we've always done that;
1034      * (for now?) apply this restriction only on the (new) 6 GHz band.
1035      */
1036     if (*capab & WLAN_CAPABILITY_SPECTRUM_MGMT &&
1037         (sband->band != NL80211_BAND_6GHZ ||
1038          !ext_capa || ext_capa->datalen < 1 ||
1039          !(ext_capa->data[0] & WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING))) {
1040         /* TODO: get this in reg domain format */
1041         pos = skb_put(skb, 2 * sband->n_channels + 2);
1042         *pos++ = WLAN_EID_SUPPORTED_CHANNELS;
1043         *pos++ = 2 * sband->n_channels;
1044         for (i = 0; i < sband->n_channels; i++) {
1045             int cf = sband->channels[i].center_freq;
1046 
1047             *pos++ = ieee80211_frequency_to_channel(cf);
1048             *pos++ = 1; /* one channel in the subband*/
1049         }
1050         ADD_PRESENT_ELEM(WLAN_EID_SUPPORTED_CHANNELS);
1051     }
1052 
1053     /* if present, add any custom IEs that go before HT */
1054     offset = ieee80211_add_before_ht_elems(skb, extra_elems,
1055                            extra_elems_len,
1056                            offset);
1057 
1058     if (sband->band != NL80211_BAND_6GHZ &&
1059         !(assoc_data->link[link_id].conn_flags & IEEE80211_CONN_DISABLE_HT)) {
1060         ieee80211_add_ht_ie(sdata, skb,
1061                     assoc_data->link[link_id].ap_ht_param,
1062                     sband, chan, smps_mode,
1063                     assoc_data->link[link_id].conn_flags);
1064         ADD_PRESENT_ELEM(WLAN_EID_HT_CAPABILITY);
1065     }
1066 
1067     /* if present, add any custom IEs that go before VHT */
1068     offset = ieee80211_add_before_vht_elems(skb, extra_elems,
1069                         extra_elems_len,
1070                         offset);
1071 
1072     if (sband->band != NL80211_BAND_6GHZ &&
1073         !(assoc_data->link[link_id].conn_flags & IEEE80211_CONN_DISABLE_VHT)) {
1074         bool mu_mimo_owner =
1075             ieee80211_add_vht_ie(sdata, skb, sband,
1076                          &assoc_data->link[link_id].ap_vht_cap,
1077                          assoc_data->link[link_id].conn_flags);
1078 
1079         if (link)
1080             link->conf->mu_mimo_owner = mu_mimo_owner;
1081         ADD_PRESENT_ELEM(WLAN_EID_VHT_CAPABILITY);
1082     }
1083 
1084     /*
1085      * If AP doesn't support HT, mark HE and EHT as disabled.
1086      * If on the 5GHz band, make sure it supports VHT.
1087      */
1088     if (assoc_data->link[link_id].conn_flags & IEEE80211_CONN_DISABLE_HT ||
1089         (sband->band == NL80211_BAND_5GHZ &&
1090          assoc_data->link[link_id].conn_flags & IEEE80211_CONN_DISABLE_VHT))
1091         assoc_data->link[link_id].conn_flags |=
1092             IEEE80211_CONN_DISABLE_HE |
1093             IEEE80211_CONN_DISABLE_EHT;
1094 
1095     /* if present, add any custom IEs that go before HE */
1096     offset = ieee80211_add_before_he_elems(skb, extra_elems,
1097                            extra_elems_len,
1098                            offset);
1099 
1100     if (!(assoc_data->link[link_id].conn_flags & IEEE80211_CONN_DISABLE_HE)) {
1101         ieee80211_add_he_ie(sdata, skb, sband,
1102                     assoc_data->link[link_id].conn_flags);
1103         ADD_PRESENT_EXT_ELEM(WLAN_EID_EXT_HE_CAPABILITY);
1104     }
1105 
1106     /*
1107      * careful - need to know about all the present elems before
1108      * calling ieee80211_assoc_add_ml_elem(), so add this one if
1109      * we're going to put it after the ML element
1110      */
1111     if (!(assoc_data->link[link_id].conn_flags & IEEE80211_CONN_DISABLE_EHT))
1112         ADD_PRESENT_EXT_ELEM(WLAN_EID_EXT_EHT_CAPABILITY);
1113 
1114     if (link_id == assoc_data->assoc_link_id)
1115         ieee80211_assoc_add_ml_elem(sdata, skb, orig_capab, ext_capa,
1116                         present_elems);
1117 
1118     /* crash if somebody gets it wrong */
1119     present_elems = NULL;
1120 
1121     if (!(assoc_data->link[link_id].conn_flags & IEEE80211_CONN_DISABLE_EHT))
1122         ieee80211_add_eht_ie(sdata, skb, sband);
1123 
1124     if (sband->band == NL80211_BAND_S1GHZ) {
1125         ieee80211_add_aid_request_ie(sdata, skb);
1126         ieee80211_add_s1g_capab_ie(sdata, &sband->s1g_cap, skb);
1127     }
1128 
1129     if (iftd && iftd->vendor_elems.data && iftd->vendor_elems.len)
1130         skb_put_data(skb, iftd->vendor_elems.data, iftd->vendor_elems.len);
1131 
1132     if (link)
1133         link->u.mgd.conn_flags = assoc_data->link[link_id].conn_flags;
1134 
1135     return offset;
1136 }
1137 
1138 static void ieee80211_add_non_inheritance_elem(struct sk_buff *skb,
1139                            const u16 *outer,
1140                            const u16 *inner)
1141 {
1142     unsigned int skb_len = skb->len;
1143     bool added = false;
1144     int i, j;
1145     u8 *len, *list_len = NULL;
1146 
1147     skb_put_u8(skb, WLAN_EID_EXTENSION);
1148     len = skb_put(skb, 1);
1149     skb_put_u8(skb, WLAN_EID_EXT_NON_INHERITANCE);
1150 
1151     for (i = 0; i < PRESENT_ELEMS_MAX && outer[i]; i++) {
1152         u16 elem = outer[i];
1153         bool have_inner = false;
1154         bool at_extension = false;
1155 
1156         /* should at least be sorted in the sense of normal -> ext */
1157         WARN_ON(at_extension && elem < PRESENT_ELEM_EXT_OFFS);
1158 
1159         /* switch to extension list */
1160         if (!at_extension && elem >= PRESENT_ELEM_EXT_OFFS) {
1161             at_extension = true;
1162             if (!list_len)
1163                 skb_put_u8(skb, 0);
1164             list_len = NULL;
1165         }
1166 
1167         for (j = 0; j < PRESENT_ELEMS_MAX && inner[j]; j++) {
1168             if (elem == inner[j]) {
1169                 have_inner = true;
1170                 break;
1171             }
1172         }
1173 
1174         if (have_inner)
1175             continue;
1176 
1177         if (!list_len) {
1178             list_len = skb_put(skb, 1);
1179             *list_len = 0;
1180         }
1181         *list_len += 1;
1182         skb_put_u8(skb, (u8)elem);
1183     }
1184 
1185     if (!added)
1186         skb_trim(skb, skb_len);
1187     else
1188         *len = skb->len - skb_len - 2;
1189 }
1190 
1191 static void ieee80211_assoc_add_ml_elem(struct ieee80211_sub_if_data *sdata,
1192                     struct sk_buff *skb, u16 capab,
1193                     const struct element *ext_capa,
1194                     const u16 *outer_present_elems)
1195 {
1196     struct ieee80211_local *local = sdata->local;
1197     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1198     struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
1199     struct ieee80211_multi_link_elem *ml_elem;
1200     struct ieee80211_mle_basic_common_info *common;
1201     const struct wiphy_iftype_ext_capab *ift_ext_capa;
1202     __le16 eml_capa = 0, mld_capa_ops = 0;
1203     unsigned int link_id;
1204     u8 *ml_elem_len;
1205     void *capab_pos;
1206 
1207     if (!sdata->vif.valid_links)
1208         return;
1209 
1210     ift_ext_capa = cfg80211_get_iftype_ext_capa(local->hw.wiphy,
1211                             ieee80211_vif_type_p2p(&sdata->vif));
1212     if (ift_ext_capa) {
1213         eml_capa = cpu_to_le16(ift_ext_capa->eml_capabilities);
1214         mld_capa_ops = cpu_to_le16(ift_ext_capa->mld_capa_and_ops);
1215     }
1216 
1217     skb_put_u8(skb, WLAN_EID_EXTENSION);
1218     ml_elem_len = skb_put(skb, 1);
1219     skb_put_u8(skb, WLAN_EID_EXT_EHT_MULTI_LINK);
1220     ml_elem = skb_put(skb, sizeof(*ml_elem));
1221     ml_elem->control =
1222         cpu_to_le16(IEEE80211_ML_CONTROL_TYPE_BASIC |
1223                 IEEE80211_MLC_BASIC_PRES_EML_CAPA |
1224                 IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP);
1225     common = skb_put(skb, sizeof(*common));
1226     common->len = sizeof(*common) +
1227               2 + /* EML capabilities */
1228               2;  /* MLD capa/ops */
1229     memcpy(common->mld_mac_addr, sdata->vif.addr, ETH_ALEN);
1230     skb_put_data(skb, &eml_capa, sizeof(eml_capa));
1231     /* need indication from userspace to support this */
1232     mld_capa_ops &= ~cpu_to_le16(IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP);
1233     skb_put_data(skb, &mld_capa_ops, sizeof(mld_capa_ops));
1234 
1235     for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
1236         u16 link_present_elems[PRESENT_ELEMS_MAX] = {};
1237         const u8 *extra_elems;
1238         size_t extra_elems_len;
1239         size_t extra_used;
1240         u8 *subelem_len = NULL;
1241         __le16 ctrl;
1242 
1243         if (!assoc_data->link[link_id].bss ||
1244             link_id == assoc_data->assoc_link_id)
1245             continue;
1246 
1247         extra_elems = assoc_data->link[link_id].elems;
1248         extra_elems_len = assoc_data->link[link_id].elems_len;
1249 
1250         skb_put_u8(skb, IEEE80211_MLE_SUBELEM_PER_STA_PROFILE);
1251         subelem_len = skb_put(skb, 1);
1252 
1253         ctrl = cpu_to_le16(link_id |
1254                    IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE |
1255                    IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT);
1256         skb_put_data(skb, &ctrl, sizeof(ctrl));
1257         skb_put_u8(skb, 1 + ETH_ALEN); /* STA Info Length */
1258         skb_put_data(skb, assoc_data->link[link_id].addr,
1259                  ETH_ALEN);
1260         /*
1261          * Now add the contents of the (re)association request,
1262          * but the "listen interval" and "current AP address"
1263          * (if applicable) are skipped. So we only have
1264          * the capability field (remember the position and fill
1265          * later), followed by the elements added below by
1266          * calling ieee80211_assoc_link_elems().
1267          */
1268         capab_pos = skb_put(skb, 2);
1269 
1270         extra_used = ieee80211_assoc_link_elems(sdata, skb, &capab,
1271                             ext_capa,
1272                             extra_elems,
1273                             extra_elems_len,
1274                             link_id, NULL,
1275                             link_present_elems);
1276         if (extra_elems)
1277             skb_put_data(skb, extra_elems + extra_used,
1278                      extra_elems_len - extra_used);
1279 
1280         put_unaligned_le16(capab, capab_pos);
1281 
1282         ieee80211_add_non_inheritance_elem(skb, outer_present_elems,
1283                            link_present_elems);
1284 
1285         ieee80211_fragment_element(skb, subelem_len);
1286     }
1287 
1288     ieee80211_fragment_element(skb, ml_elem_len);
1289 }
1290 
1291 static int ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
1292 {
1293     struct ieee80211_local *local = sdata->local;
1294     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1295     struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
1296     struct ieee80211_link_data *link;
1297     struct sk_buff *skb;
1298     struct ieee80211_mgmt *mgmt;
1299     u8 *pos, qos_info, *ie_start;
1300     size_t offset, noffset;
1301     u16 capab = WLAN_CAPABILITY_ESS, link_capab;
1302     __le16 listen_int;
1303     struct element *ext_capa = NULL;
1304     enum nl80211_iftype iftype = ieee80211_vif_type_p2p(&sdata->vif);
1305     struct ieee80211_prep_tx_info info = {};
1306     unsigned int link_id, n_links = 0;
1307     u16 present_elems[PRESENT_ELEMS_MAX] = {};
1308     void *capab_pos;
1309     size_t size;
1310     int ret;
1311 
1312     /* we know it's writable, cast away the const */
1313     if (assoc_data->ie_len)
1314         ext_capa = (void *)cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY,
1315                               assoc_data->ie,
1316                               assoc_data->ie_len);
1317 
1318     sdata_assert_lock(sdata);
1319 
1320     size = local->hw.extra_tx_headroom +
1321            sizeof(*mgmt) + /* bit too much but doesn't matter */
1322            2 + assoc_data->ssid_len + /* SSID */
1323            assoc_data->ie_len + /* extra IEs */
1324            (assoc_data->fils_kek_len ? 16 /* AES-SIV */ : 0) +
1325            9; /* WMM */
1326 
1327     for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
1328         struct cfg80211_bss *cbss = assoc_data->link[link_id].bss;
1329         const struct ieee80211_sband_iftype_data *iftd;
1330         struct ieee80211_supported_band *sband;
1331 
1332         if (!cbss)
1333             continue;
1334 
1335         sband = local->hw.wiphy->bands[cbss->channel->band];
1336 
1337         n_links++;
1338         /* add STA profile elements length */
1339         size += assoc_data->link[link_id].elems_len;
1340         /* and supported rates length */
1341         size += 4 + sband->n_bitrates;
1342         /* supported channels */
1343         size += 2 + 2 * sband->n_channels;
1344 
1345         iftd = ieee80211_get_sband_iftype_data(sband, iftype);
1346         if (iftd)
1347             size += iftd->vendor_elems.len;
1348 
1349         /* power capability */
1350         size += 4;
1351 
1352         /* HT, VHT, HE, EHT */
1353         size += 2 + sizeof(struct ieee80211_ht_cap);
1354         size += 2 + sizeof(struct ieee80211_vht_cap);
1355         size += 2 + 1 + sizeof(struct ieee80211_he_cap_elem) +
1356             sizeof(struct ieee80211_he_mcs_nss_supp) +
1357             IEEE80211_HE_PPE_THRES_MAX_LEN;
1358 
1359         if (sband->band == NL80211_BAND_6GHZ)
1360             size += 2 + 1 + sizeof(struct ieee80211_he_6ghz_capa);
1361 
1362         size += 2 + 1 + sizeof(struct ieee80211_eht_cap_elem) +
1363             sizeof(struct ieee80211_eht_mcs_nss_supp) +
1364             IEEE80211_EHT_PPE_THRES_MAX_LEN;
1365 
1366         /* non-inheritance element */
1367         size += 2 + 2 + PRESENT_ELEMS_MAX;
1368 
1369         /* should be the same across all BSSes */
1370         if (cbss->capability & WLAN_CAPABILITY_PRIVACY)
1371             capab |= WLAN_CAPABILITY_PRIVACY;
1372     }
1373 
1374     if (sdata->vif.valid_links) {
1375         /* consider the multi-link element with STA profile */
1376         size += sizeof(struct ieee80211_multi_link_elem);
1377         /* max common info field in basic multi-link element */
1378         size += sizeof(struct ieee80211_mle_basic_common_info) +
1379             2 + /* capa & op */
1380             2; /* EML capa */
1381 
1382         /*
1383          * The capability elements were already considered above;
1384          * note this over-estimates a bit because there's no
1385          * STA profile for the assoc link.
1386          */
1387         size += (n_links - 1) *
1388             (1 + 1 + /* subelement ID/length */
1389              2 + /* STA control */
1390              1 + ETH_ALEN + 2 /* STA Info field */);
1391     }
1392 
1393     link = sdata_dereference(sdata->link[assoc_data->assoc_link_id], sdata);
1394     if (WARN_ON(!link))
1395         return -EINVAL;
1396 
1397     if (WARN_ON(!assoc_data->link[assoc_data->assoc_link_id].bss))
1398         return -EINVAL;
1399 
1400     skb = alloc_skb(size, GFP_KERNEL);
1401     if (!skb)
1402         return -ENOMEM;
1403 
1404     skb_reserve(skb, local->hw.extra_tx_headroom);
1405 
1406     if (ifmgd->flags & IEEE80211_STA_ENABLE_RRM)
1407         capab |= WLAN_CAPABILITY_RADIO_MEASURE;
1408 
1409     /* Set MBSSID support for HE AP if needed */
1410     if (ieee80211_hw_check(&local->hw, SUPPORTS_ONLY_HE_MULTI_BSSID) &&
1411         !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HE) &&
1412         ext_capa && ext_capa->datalen >= 3)
1413         ext_capa->data[2] |= WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT;
1414 
1415     mgmt = skb_put_zero(skb, 24);
1416     memcpy(mgmt->da, sdata->vif.cfg.ap_addr, ETH_ALEN);
1417     memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
1418     memcpy(mgmt->bssid, sdata->vif.cfg.ap_addr, ETH_ALEN);
1419 
1420     listen_int = cpu_to_le16(assoc_data->s1g ?
1421             ieee80211_encode_usf(local->hw.conf.listen_interval) :
1422             local->hw.conf.listen_interval);
1423     if (!is_zero_ether_addr(assoc_data->prev_ap_addr)) {
1424         skb_put(skb, 10);
1425         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1426                           IEEE80211_STYPE_REASSOC_REQ);
1427         capab_pos = &mgmt->u.reassoc_req.capab_info;
1428         mgmt->u.reassoc_req.listen_interval = listen_int;
1429         memcpy(mgmt->u.reassoc_req.current_ap,
1430                assoc_data->prev_ap_addr, ETH_ALEN);
1431         info.subtype = IEEE80211_STYPE_REASSOC_REQ;
1432     } else {
1433         skb_put(skb, 4);
1434         mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1435                           IEEE80211_STYPE_ASSOC_REQ);
1436         capab_pos = &mgmt->u.assoc_req.capab_info;
1437         mgmt->u.assoc_req.listen_interval = listen_int;
1438         info.subtype = IEEE80211_STYPE_ASSOC_REQ;
1439     }
1440 
1441     /* SSID */
1442     pos = skb_put(skb, 2 + assoc_data->ssid_len);
1443     ie_start = pos;
1444     *pos++ = WLAN_EID_SSID;
1445     *pos++ = assoc_data->ssid_len;
1446     memcpy(pos, assoc_data->ssid, assoc_data->ssid_len);
1447 
1448     /* add the elements for the assoc (main) link */
1449     link_capab = capab;
1450     offset = ieee80211_assoc_link_elems(sdata, skb, &link_capab,
1451                         ext_capa,
1452                         assoc_data->ie,
1453                         assoc_data->ie_len,
1454                         assoc_data->assoc_link_id, link,
1455                         present_elems);
1456     put_unaligned_le16(link_capab, capab_pos);
1457 
1458     /* if present, add any custom non-vendor IEs */
1459     if (assoc_data->ie_len) {
1460         noffset = ieee80211_ie_split_vendor(assoc_data->ie,
1461                             assoc_data->ie_len,
1462                             offset);
1463         skb_put_data(skb, assoc_data->ie + offset, noffset - offset);
1464         offset = noffset;
1465     }
1466 
1467     if (assoc_data->wmm) {
1468         if (assoc_data->uapsd) {
1469             qos_info = ifmgd->uapsd_queues;
1470             qos_info |= (ifmgd->uapsd_max_sp_len <<
1471                      IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
1472         } else {
1473             qos_info = 0;
1474         }
1475 
1476         pos = ieee80211_add_wmm_info_ie(skb_put(skb, 9), qos_info);
1477     }
1478 
1479     /* add any remaining custom (i.e. vendor specific here) IEs */
1480     if (assoc_data->ie_len) {
1481         noffset = assoc_data->ie_len;
1482         skb_put_data(skb, assoc_data->ie + offset, noffset - offset);
1483     }
1484 
1485     if (assoc_data->fils_kek_len) {
1486         ret = fils_encrypt_assoc_req(skb, assoc_data);
1487         if (ret < 0) {
1488             dev_kfree_skb(skb);
1489             return ret;
1490         }
1491     }
1492 
1493     pos = skb_tail_pointer(skb);
1494     kfree(ifmgd->assoc_req_ies);
1495     ifmgd->assoc_req_ies = kmemdup(ie_start, pos - ie_start, GFP_ATOMIC);
1496     if (!ifmgd->assoc_req_ies) {
1497         dev_kfree_skb(skb);
1498         return -ENOMEM;
1499     }
1500 
1501     ifmgd->assoc_req_ies_len = pos - ie_start;
1502 
1503     drv_mgd_prepare_tx(local, sdata, &info);
1504 
1505     IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
1506     if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
1507         IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS |
1508                         IEEE80211_TX_INTFL_MLME_CONN_TX;
1509     ieee80211_tx_skb(sdata, skb);
1510 
1511     return 0;
1512 }
1513 
1514 void ieee80211_send_pspoll(struct ieee80211_local *local,
1515                struct ieee80211_sub_if_data *sdata)
1516 {
1517     struct ieee80211_pspoll *pspoll;
1518     struct sk_buff *skb;
1519 
1520     skb = ieee80211_pspoll_get(&local->hw, &sdata->vif);
1521     if (!skb)
1522         return;
1523 
1524     pspoll = (struct ieee80211_pspoll *) skb->data;
1525     pspoll->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
1526 
1527     IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
1528     ieee80211_tx_skb(sdata, skb);
1529 }
1530 
1531 void ieee80211_send_nullfunc(struct ieee80211_local *local,
1532                  struct ieee80211_sub_if_data *sdata,
1533                  bool powersave)
1534 {
1535     struct sk_buff *skb;
1536     struct ieee80211_hdr_3addr *nullfunc;
1537     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1538 
1539     skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif,
1540         !ieee80211_hw_check(&local->hw, DOESNT_SUPPORT_QOS_NDP));
1541     if (!skb)
1542         return;
1543 
1544     nullfunc = (struct ieee80211_hdr_3addr *) skb->data;
1545     if (powersave)
1546         nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
1547 
1548     IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
1549                     IEEE80211_TX_INTFL_OFFCHAN_TX_OK;
1550 
1551     if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
1552         IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
1553 
1554     if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL)
1555         IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE;
1556 
1557     ieee80211_tx_skb(sdata, skb);
1558 }
1559 
1560 void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local,
1561                    struct ieee80211_sub_if_data *sdata)
1562 {
1563     struct sk_buff *skb;
1564     struct ieee80211_hdr *nullfunc;
1565     __le16 fc;
1566 
1567     if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
1568         return;
1569 
1570     skb = dev_alloc_skb(local->hw.extra_tx_headroom + 30);
1571     if (!skb)
1572         return;
1573 
1574     skb_reserve(skb, local->hw.extra_tx_headroom);
1575 
1576     nullfunc = skb_put_zero(skb, 30);
1577     fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
1578              IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
1579     nullfunc->frame_control = fc;
1580     memcpy(nullfunc->addr1, sdata->deflink.u.mgd.bssid, ETH_ALEN);
1581     memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
1582     memcpy(nullfunc->addr3, sdata->deflink.u.mgd.bssid, ETH_ALEN);
1583     memcpy(nullfunc->addr4, sdata->vif.addr, ETH_ALEN);
1584 
1585     IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
1586     IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE;
1587     ieee80211_tx_skb(sdata, skb);
1588 }
1589 
1590 /* spectrum management related things */
1591 static void ieee80211_chswitch_work(struct work_struct *work)
1592 {
1593     struct ieee80211_link_data *link =
1594         container_of(work, struct ieee80211_link_data, u.mgd.chswitch_work);
1595     struct ieee80211_sub_if_data *sdata = link->sdata;
1596     struct ieee80211_local *local = sdata->local;
1597     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1598     int ret;
1599 
1600     if (!ieee80211_sdata_running(sdata))
1601         return;
1602 
1603     sdata_lock(sdata);
1604     mutex_lock(&local->mtx);
1605     mutex_lock(&local->chanctx_mtx);
1606 
1607     if (!ifmgd->associated)
1608         goto out;
1609 
1610     if (!link->conf->csa_active)
1611         goto out;
1612 
1613     /*
1614      * using reservation isn't immediate as it may be deferred until later
1615      * with multi-vif. once reservation is complete it will re-schedule the
1616      * work with no reserved_chanctx so verify chandef to check if it
1617      * completed successfully
1618      */
1619 
1620     if (link->reserved_chanctx) {
1621         /*
1622          * with multi-vif csa driver may call ieee80211_csa_finish()
1623          * many times while waiting for other interfaces to use their
1624          * reservations
1625          */
1626         if (link->reserved_ready)
1627             goto out;
1628 
1629         ret = ieee80211_link_use_reserved_context(link);
1630         if (ret) {
1631             sdata_info(sdata,
1632                    "failed to use reserved channel context, disconnecting (err=%d)\n",
1633                    ret);
1634             ieee80211_queue_work(&sdata->local->hw,
1635                          &ifmgd->csa_connection_drop_work);
1636             goto out;
1637         }
1638 
1639         goto out;
1640     }
1641 
1642     if (!cfg80211_chandef_identical(&link->conf->chandef,
1643                     &link->csa_chandef)) {
1644         sdata_info(sdata,
1645                "failed to finalize channel switch, disconnecting\n");
1646         ieee80211_queue_work(&sdata->local->hw,
1647                      &ifmgd->csa_connection_drop_work);
1648         goto out;
1649     }
1650 
1651     link->u.mgd.csa_waiting_bcn = true;
1652 
1653     ieee80211_sta_reset_beacon_monitor(sdata);
1654     ieee80211_sta_reset_conn_monitor(sdata);
1655 
1656 out:
1657     mutex_unlock(&local->chanctx_mtx);
1658     mutex_unlock(&local->mtx);
1659     sdata_unlock(sdata);
1660 }
1661 
1662 static void ieee80211_chswitch_post_beacon(struct ieee80211_link_data *link)
1663 {
1664     struct ieee80211_sub_if_data *sdata = link->sdata;
1665     struct ieee80211_local *local = sdata->local;
1666     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1667     int ret;
1668 
1669     sdata_assert_lock(sdata);
1670 
1671     WARN_ON(!link->conf->csa_active);
1672 
1673     if (link->csa_block_tx) {
1674         ieee80211_wake_vif_queues(local, sdata,
1675                       IEEE80211_QUEUE_STOP_REASON_CSA);
1676         link->csa_block_tx = false;
1677     }
1678 
1679     link->conf->csa_active = false;
1680     link->u.mgd.csa_waiting_bcn = false;
1681     /*
1682      * If the CSA IE is still present on the beacon after the switch,
1683      * we need to consider it as a new CSA (possibly to self).
1684      */
1685     link->u.mgd.beacon_crc_valid = false;
1686 
1687     ret = drv_post_channel_switch(sdata);
1688     if (ret) {
1689         sdata_info(sdata,
1690                "driver post channel switch failed, disconnecting\n");
1691         ieee80211_queue_work(&local->hw,
1692                      &ifmgd->csa_connection_drop_work);
1693         return;
1694     }
1695 
1696     cfg80211_ch_switch_notify(sdata->dev, &link->reserved_chandef, 0);
1697 }
1698 
1699 void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
1700 {
1701     struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1702     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1703 
1704     if (WARN_ON(sdata->vif.valid_links))
1705         success = false;
1706 
1707     trace_api_chswitch_done(sdata, success);
1708     if (!success) {
1709         sdata_info(sdata,
1710                "driver channel switch failed, disconnecting\n");
1711         ieee80211_queue_work(&sdata->local->hw,
1712                      &ifmgd->csa_connection_drop_work);
1713     } else {
1714         ieee80211_queue_work(&sdata->local->hw,
1715                      &sdata->deflink.u.mgd.chswitch_work);
1716     }
1717 }
1718 EXPORT_SYMBOL(ieee80211_chswitch_done);
1719 
1720 static void ieee80211_chswitch_timer(struct timer_list *t)
1721 {
1722     struct ieee80211_link_data *link =
1723         from_timer(link, t, u.mgd.chswitch_timer);
1724 
1725     ieee80211_queue_work(&link->sdata->local->hw,
1726                  &link->u.mgd.chswitch_work);
1727 }
1728 
1729 static void
1730 ieee80211_sta_abort_chanswitch(struct ieee80211_link_data *link)
1731 {
1732     struct ieee80211_sub_if_data *sdata = link->sdata;
1733     struct ieee80211_local *local = sdata->local;
1734 
1735     if (!local->ops->abort_channel_switch)
1736         return;
1737 
1738     mutex_lock(&local->mtx);
1739 
1740     mutex_lock(&local->chanctx_mtx);
1741     ieee80211_link_unreserve_chanctx(link);
1742     mutex_unlock(&local->chanctx_mtx);
1743 
1744     if (link->csa_block_tx)
1745         ieee80211_wake_vif_queues(local, sdata,
1746                       IEEE80211_QUEUE_STOP_REASON_CSA);
1747 
1748     link->csa_block_tx = false;
1749     link->conf->csa_active = false;
1750 
1751     mutex_unlock(&local->mtx);
1752 
1753     drv_abort_channel_switch(sdata);
1754 }
1755 
1756 static void
1757 ieee80211_sta_process_chanswitch(struct ieee80211_link_data *link,
1758                  u64 timestamp, u32 device_timestamp,
1759                  struct ieee802_11_elems *elems,
1760                  bool beacon)
1761 {
1762     struct ieee80211_sub_if_data *sdata = link->sdata;
1763     struct ieee80211_local *local = sdata->local;
1764     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1765     struct cfg80211_bss *cbss = link->u.mgd.bss;
1766     struct ieee80211_chanctx_conf *conf;
1767     struct ieee80211_chanctx *chanctx;
1768     enum nl80211_band current_band;
1769     struct ieee80211_csa_ie csa_ie;
1770     struct ieee80211_channel_switch ch_switch;
1771     struct ieee80211_bss *bss;
1772     int res;
1773 
1774     sdata_assert_lock(sdata);
1775 
1776     if (!cbss)
1777         return;
1778 
1779     if (local->scanning)
1780         return;
1781 
1782     current_band = cbss->channel->band;
1783     bss = (void *)cbss->priv;
1784     res = ieee80211_parse_ch_switch_ie(sdata, elems, current_band,
1785                        bss->vht_cap_info,
1786                        link->u.mgd.conn_flags,
1787                        link->u.mgd.bssid, &csa_ie);
1788 
1789     if (!res) {
1790         ch_switch.timestamp = timestamp;
1791         ch_switch.device_timestamp = device_timestamp;
1792         ch_switch.block_tx = csa_ie.mode;
1793         ch_switch.chandef = csa_ie.chandef;
1794         ch_switch.count = csa_ie.count;
1795         ch_switch.delay = csa_ie.max_switch_time;
1796     }
1797 
1798     if (res < 0)
1799         goto lock_and_drop_connection;
1800 
1801     if (beacon && link->conf->csa_active &&
1802         !link->u.mgd.csa_waiting_bcn) {
1803         if (res)
1804             ieee80211_sta_abort_chanswitch(link);
1805         else
1806             drv_channel_switch_rx_beacon(sdata, &ch_switch);
1807         return;
1808     } else if (link->conf->csa_active || res) {
1809         /* disregard subsequent announcements if already processing */
1810         return;
1811     }
1812 
1813     if (link->conf->chandef.chan->band !=
1814         csa_ie.chandef.chan->band) {
1815         sdata_info(sdata,
1816                "AP %pM switches to different band (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n",
1817                link->u.mgd.bssid,
1818                csa_ie.chandef.chan->center_freq,
1819                csa_ie.chandef.width, csa_ie.chandef.center_freq1,
1820                csa_ie.chandef.center_freq2);
1821         goto lock_and_drop_connection;
1822     }
1823 
1824     if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef,
1825                      IEEE80211_CHAN_DISABLED)) {
1826         sdata_info(sdata,
1827                "AP %pM switches to unsupported channel "
1828                "(%d.%03d MHz, width:%d, CF1/2: %d.%03d/%d MHz), "
1829                "disconnecting\n",
1830                link->u.mgd.bssid,
1831                csa_ie.chandef.chan->center_freq,
1832                csa_ie.chandef.chan->freq_offset,
1833                csa_ie.chandef.width, csa_ie.chandef.center_freq1,
1834                csa_ie.chandef.freq1_offset,
1835                csa_ie.chandef.center_freq2);
1836         goto lock_and_drop_connection;
1837     }
1838 
1839     if (cfg80211_chandef_identical(&csa_ie.chandef,
1840                        &link->conf->chandef) &&
1841         (!csa_ie.mode || !beacon)) {
1842         if (link->u.mgd.csa_ignored_same_chan)
1843             return;
1844         sdata_info(sdata,
1845                "AP %pM tries to chanswitch to same channel, ignore\n",
1846                link->u.mgd.bssid);
1847         link->u.mgd.csa_ignored_same_chan = true;
1848         return;
1849     }
1850 
1851     /*
1852      * Drop all TDLS peers - either we disconnect or move to a different
1853      * channel from this point on. There's no telling what our peer will do.
1854      * The TDLS WIDER_BW scenario is also problematic, as peers might now
1855      * have an incompatible wider chandef.
1856      */
1857     ieee80211_teardown_tdls_peers(sdata);
1858 
1859     mutex_lock(&local->mtx);
1860     mutex_lock(&local->chanctx_mtx);
1861     conf = rcu_dereference_protected(link->conf->chanctx_conf,
1862                      lockdep_is_held(&local->chanctx_mtx));
1863     if (!conf) {
1864         sdata_info(sdata,
1865                "no channel context assigned to vif?, disconnecting\n");
1866         goto drop_connection;
1867     }
1868 
1869     chanctx = container_of(conf, struct ieee80211_chanctx, conf);
1870 
1871     if (local->use_chanctx &&
1872         !ieee80211_hw_check(&local->hw, CHANCTX_STA_CSA)) {
1873         sdata_info(sdata,
1874                "driver doesn't support chan-switch with channel contexts\n");
1875         goto drop_connection;
1876     }
1877 
1878     if (drv_pre_channel_switch(sdata, &ch_switch)) {
1879         sdata_info(sdata,
1880                "preparing for channel switch failed, disconnecting\n");
1881         goto drop_connection;
1882     }
1883 
1884     res = ieee80211_link_reserve_chanctx(link, &csa_ie.chandef,
1885                          chanctx->mode, false);
1886     if (res) {
1887         sdata_info(sdata,
1888                "failed to reserve channel context for channel switch, disconnecting (err=%d)\n",
1889                res);
1890         goto drop_connection;
1891     }
1892     mutex_unlock(&local->chanctx_mtx);
1893 
1894     link->conf->csa_active = true;
1895     link->csa_chandef = csa_ie.chandef;
1896     link->csa_block_tx = csa_ie.mode;
1897     link->u.mgd.csa_ignored_same_chan = false;
1898     link->u.mgd.beacon_crc_valid = false;
1899 
1900     if (link->csa_block_tx)
1901         ieee80211_stop_vif_queues(local, sdata,
1902                       IEEE80211_QUEUE_STOP_REASON_CSA);
1903     mutex_unlock(&local->mtx);
1904 
1905     cfg80211_ch_switch_started_notify(sdata->dev, &csa_ie.chandef,
1906                       csa_ie.count, csa_ie.mode);
1907 
1908     if (local->ops->channel_switch) {
1909         /* use driver's channel switch callback */
1910         drv_channel_switch(local, sdata, &ch_switch);
1911         return;
1912     }
1913 
1914     /* channel switch handled in software */
1915     if (csa_ie.count <= 1)
1916         ieee80211_queue_work(&local->hw, &link->u.mgd.chswitch_work);
1917     else
1918         mod_timer(&link->u.mgd.chswitch_timer,
1919               TU_TO_EXP_TIME((csa_ie.count - 1) *
1920                      cbss->beacon_interval));
1921     return;
1922  lock_and_drop_connection:
1923     mutex_lock(&local->mtx);
1924     mutex_lock(&local->chanctx_mtx);
1925  drop_connection:
1926     /*
1927      * This is just so that the disconnect flow will know that
1928      * we were trying to switch channel and failed. In case the
1929      * mode is 1 (we are not allowed to Tx), we will know not to
1930      * send a deauthentication frame. Those two fields will be
1931      * reset when the disconnection worker runs.
1932      */
1933     link->conf->csa_active = true;
1934     link->csa_block_tx = csa_ie.mode;
1935 
1936     ieee80211_queue_work(&local->hw, &ifmgd->csa_connection_drop_work);
1937     mutex_unlock(&local->chanctx_mtx);
1938     mutex_unlock(&local->mtx);
1939 }
1940 
1941 static bool
1942 ieee80211_find_80211h_pwr_constr(struct ieee80211_sub_if_data *sdata,
1943                  struct ieee80211_channel *channel,
1944                  const u8 *country_ie, u8 country_ie_len,
1945                  const u8 *pwr_constr_elem,
1946                  int *chan_pwr, int *pwr_reduction)
1947 {
1948     struct ieee80211_country_ie_triplet *triplet;
1949     int chan = ieee80211_frequency_to_channel(channel->center_freq);
1950     int i, chan_increment;
1951     bool have_chan_pwr = false;
1952 
1953     /* Invalid IE */
1954     if (country_ie_len % 2 || country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
1955         return false;
1956 
1957     triplet = (void *)(country_ie + 3);
1958     country_ie_len -= 3;
1959 
1960     switch (channel->band) {
1961     default:
1962         WARN_ON_ONCE(1);
1963         fallthrough;
1964     case NL80211_BAND_2GHZ:
1965     case NL80211_BAND_60GHZ:
1966     case NL80211_BAND_LC:
1967         chan_increment = 1;
1968         break;
1969     case NL80211_BAND_5GHZ:
1970         chan_increment = 4;
1971         break;
1972     case NL80211_BAND_6GHZ:
1973         /*
1974          * In the 6 GHz band, the "maximum transmit power level"
1975          * field in the triplets is reserved, and thus will be
1976          * zero and we shouldn't use it to control TX power.
1977          * The actual TX power will be given in the transmit
1978          * power envelope element instead.
1979          */
1980         return false;
1981     }
1982 
1983     /* find channel */
1984     while (country_ie_len >= 3) {
1985         u8 first_channel = triplet->chans.first_channel;
1986 
1987         if (first_channel >= IEEE80211_COUNTRY_EXTENSION_ID)
1988             goto next;
1989 
1990         for (i = 0; i < triplet->chans.num_channels; i++) {
1991             if (first_channel + i * chan_increment == chan) {
1992                 have_chan_pwr = true;
1993                 *chan_pwr = triplet->chans.max_power;
1994                 break;
1995             }
1996         }
1997         if (have_chan_pwr)
1998             break;
1999 
2000  next:
2001         triplet++;
2002         country_ie_len -= 3;
2003     }
2004 
2005     if (have_chan_pwr && pwr_constr_elem)
2006         *pwr_reduction = *pwr_constr_elem;
2007     else
2008         *pwr_reduction = 0;
2009 
2010     return have_chan_pwr;
2011 }
2012 
2013 static void ieee80211_find_cisco_dtpc(struct ieee80211_sub_if_data *sdata,
2014                       struct ieee80211_channel *channel,
2015                       const u8 *cisco_dtpc_ie,
2016                       int *pwr_level)
2017 {
2018     /* From practical testing, the first data byte of the DTPC element
2019      * seems to contain the requested dBm level, and the CLI on Cisco
2020      * APs clearly state the range is -127 to 127 dBm, which indicates
2021      * a signed byte, although it seemingly never actually goes negative.
2022      * The other byte seems to always be zero.
2023      */
2024     *pwr_level = (__s8)cisco_dtpc_ie[4];
2025 }
2026 
2027 static u32 ieee80211_handle_pwr_constr(struct ieee80211_link_data *link,
2028                        struct ieee80211_channel *channel,
2029                        struct ieee80211_mgmt *mgmt,
2030                        const u8 *country_ie, u8 country_ie_len,
2031                        const u8 *pwr_constr_ie,
2032                        const u8 *cisco_dtpc_ie)
2033 {
2034     struct ieee80211_sub_if_data *sdata = link->sdata;
2035     bool has_80211h_pwr = false, has_cisco_pwr = false;
2036     int chan_pwr = 0, pwr_reduction_80211h = 0;
2037     int pwr_level_cisco, pwr_level_80211h;
2038     int new_ap_level;
2039     __le16 capab = mgmt->u.probe_resp.capab_info;
2040 
2041     if (ieee80211_is_s1g_beacon(mgmt->frame_control))
2042         return 0;   /* TODO */
2043 
2044     if (country_ie &&
2045         (capab & cpu_to_le16(WLAN_CAPABILITY_SPECTRUM_MGMT) ||
2046          capab & cpu_to_le16(WLAN_CAPABILITY_RADIO_MEASURE))) {
2047         has_80211h_pwr = ieee80211_find_80211h_pwr_constr(
2048             sdata, channel, country_ie, country_ie_len,
2049             pwr_constr_ie, &chan_pwr, &pwr_reduction_80211h);
2050         pwr_level_80211h =
2051             max_t(int, 0, chan_pwr - pwr_reduction_80211h);
2052     }
2053 
2054     if (cisco_dtpc_ie) {
2055         ieee80211_find_cisco_dtpc(
2056             sdata, channel, cisco_dtpc_ie, &pwr_level_cisco);
2057         has_cisco_pwr = true;
2058     }
2059 
2060     if (!has_80211h_pwr && !has_cisco_pwr)
2061         return 0;
2062 
2063     /* If we have both 802.11h and Cisco DTPC, apply both limits
2064      * by picking the smallest of the two power levels advertised.
2065      */
2066     if (has_80211h_pwr &&
2067         (!has_cisco_pwr || pwr_level_80211h <= pwr_level_cisco)) {
2068         new_ap_level = pwr_level_80211h;
2069 
2070         if (link->ap_power_level == new_ap_level)
2071             return 0;
2072 
2073         sdata_dbg(sdata,
2074               "Limiting TX power to %d (%d - %d) dBm as advertised by %pM\n",
2075               pwr_level_80211h, chan_pwr, pwr_reduction_80211h,
2076               link->u.mgd.bssid);
2077     } else {  /* has_cisco_pwr is always true here. */
2078         new_ap_level = pwr_level_cisco;
2079 
2080         if (link->ap_power_level == new_ap_level)
2081             return 0;
2082 
2083         sdata_dbg(sdata,
2084               "Limiting TX power to %d dBm as advertised by %pM\n",
2085               pwr_level_cisco, link->u.mgd.bssid);
2086     }
2087 
2088     link->ap_power_level = new_ap_level;
2089     if (__ieee80211_recalc_txpower(sdata))
2090         return BSS_CHANGED_TXPOWER;
2091     return 0;
2092 }
2093 
2094 /* powersave */
2095 static void ieee80211_enable_ps(struct ieee80211_local *local,
2096                 struct ieee80211_sub_if_data *sdata)
2097 {
2098     struct ieee80211_conf *conf = &local->hw.conf;
2099 
2100     /*
2101      * If we are scanning right now then the parameters will
2102      * take effect when scan finishes.
2103      */
2104     if (local->scanning)
2105         return;
2106 
2107     if (conf->dynamic_ps_timeout > 0 &&
2108         !ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS)) {
2109         mod_timer(&local->dynamic_ps_timer, jiffies +
2110               msecs_to_jiffies(conf->dynamic_ps_timeout));
2111     } else {
2112         if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK))
2113             ieee80211_send_nullfunc(local, sdata, true);
2114 
2115         if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) &&
2116             ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
2117             return;
2118 
2119         conf->flags |= IEEE80211_CONF_PS;
2120         ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
2121     }
2122 }
2123 
2124 static void ieee80211_change_ps(struct ieee80211_local *local)
2125 {
2126     struct ieee80211_conf *conf = &local->hw.conf;
2127 
2128     if (local->ps_sdata) {
2129         ieee80211_enable_ps(local, local->ps_sdata);
2130     } else if (conf->flags & IEEE80211_CONF_PS) {
2131         conf->flags &= ~IEEE80211_CONF_PS;
2132         ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
2133         del_timer_sync(&local->dynamic_ps_timer);
2134         cancel_work_sync(&local->dynamic_ps_enable_work);
2135     }
2136 }
2137 
2138 static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
2139 {
2140     struct ieee80211_local *local = sdata->local;
2141     struct ieee80211_if_managed *mgd = &sdata->u.mgd;
2142     struct sta_info *sta = NULL;
2143     bool authorized = false;
2144 
2145     if (!mgd->powersave)
2146         return false;
2147 
2148     if (mgd->broken_ap)
2149         return false;
2150 
2151     if (!mgd->associated)
2152         return false;
2153 
2154     if (mgd->flags & IEEE80211_STA_CONNECTION_POLL)
2155         return false;
2156 
2157     if (!(local->hw.wiphy->flags & WIPHY_FLAG_SUPPORTS_MLO) &&
2158         !sdata->deflink.u.mgd.have_beacon)
2159         return false;
2160 
2161     rcu_read_lock();
2162     sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr);
2163     if (sta)
2164         authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
2165     rcu_read_unlock();
2166 
2167     return authorized;
2168 }
2169 
2170 /* need to hold RTNL or interface lock */
2171 void ieee80211_recalc_ps(struct ieee80211_local *local)
2172 {
2173     struct ieee80211_sub_if_data *sdata, *found = NULL;
2174     int count = 0;
2175     int timeout;
2176 
2177     if (!ieee80211_hw_check(&local->hw, SUPPORTS_PS) ||
2178         ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS)) {
2179         local->ps_sdata = NULL;
2180         return;
2181     }
2182 
2183     list_for_each_entry(sdata, &local->interfaces, list) {
2184         if (!ieee80211_sdata_running(sdata))
2185             continue;
2186         if (sdata->vif.type == NL80211_IFTYPE_AP) {
2187             /* If an AP vif is found, then disable PS
2188              * by setting the count to zero thereby setting
2189              * ps_sdata to NULL.
2190              */
2191             count = 0;
2192             break;
2193         }
2194         if (sdata->vif.type != NL80211_IFTYPE_STATION)
2195             continue;
2196         found = sdata;
2197         count++;
2198     }
2199 
2200     if (count == 1 && ieee80211_powersave_allowed(found)) {
2201         u8 dtimper = found->deflink.u.mgd.dtim_period;
2202 
2203         timeout = local->dynamic_ps_forced_timeout;
2204         if (timeout < 0)
2205             timeout = 100;
2206         local->hw.conf.dynamic_ps_timeout = timeout;
2207 
2208         /* If the TIM IE is invalid, pretend the value is 1 */
2209         if (!dtimper)
2210             dtimper = 1;
2211 
2212         local->hw.conf.ps_dtim_period = dtimper;
2213         local->ps_sdata = found;
2214     } else {
2215         local->ps_sdata = NULL;
2216     }
2217 
2218     ieee80211_change_ps(local);
2219 }
2220 
2221 void ieee80211_recalc_ps_vif(struct ieee80211_sub_if_data *sdata)
2222 {
2223     bool ps_allowed = ieee80211_powersave_allowed(sdata);
2224 
2225     if (sdata->vif.cfg.ps != ps_allowed) {
2226         sdata->vif.cfg.ps = ps_allowed;
2227         ieee80211_vif_cfg_change_notify(sdata, BSS_CHANGED_PS);
2228     }
2229 }
2230 
2231 void ieee80211_dynamic_ps_disable_work(struct work_struct *work)
2232 {
2233     struct ieee80211_local *local =
2234         container_of(work, struct ieee80211_local,
2235                  dynamic_ps_disable_work);
2236 
2237     if (local->hw.conf.flags & IEEE80211_CONF_PS) {
2238         local->hw.conf.flags &= ~IEEE80211_CONF_PS;
2239         ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
2240     }
2241 
2242     ieee80211_wake_queues_by_reason(&local->hw,
2243                     IEEE80211_MAX_QUEUE_MAP,
2244                     IEEE80211_QUEUE_STOP_REASON_PS,
2245                     false);
2246 }
2247 
2248 void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
2249 {
2250     struct ieee80211_local *local =
2251         container_of(work, struct ieee80211_local,
2252                  dynamic_ps_enable_work);
2253     struct ieee80211_sub_if_data *sdata = local->ps_sdata;
2254     struct ieee80211_if_managed *ifmgd;
2255     unsigned long flags;
2256     int q;
2257 
2258     /* can only happen when PS was just disabled anyway */
2259     if (!sdata)
2260         return;
2261 
2262     ifmgd = &sdata->u.mgd;
2263 
2264     if (local->hw.conf.flags & IEEE80211_CONF_PS)
2265         return;
2266 
2267     if (local->hw.conf.dynamic_ps_timeout > 0) {
2268         /* don't enter PS if TX frames are pending */
2269         if (drv_tx_frames_pending(local)) {
2270             mod_timer(&local->dynamic_ps_timer, jiffies +
2271                   msecs_to_jiffies(
2272                   local->hw.conf.dynamic_ps_timeout));
2273             return;
2274         }
2275 
2276         /*
2277          * transmission can be stopped by others which leads to
2278          * dynamic_ps_timer expiry. Postpone the ps timer if it
2279          * is not the actual idle state.
2280          */
2281         spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
2282         for (q = 0; q < local->hw.queues; q++) {
2283             if (local->queue_stop_reasons[q]) {
2284                 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
2285                                flags);
2286                 mod_timer(&local->dynamic_ps_timer, jiffies +
2287                       msecs_to_jiffies(
2288                       local->hw.conf.dynamic_ps_timeout));
2289                 return;
2290             }
2291         }
2292         spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
2293     }
2294 
2295     if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) &&
2296         !(ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
2297         if (drv_tx_frames_pending(local)) {
2298             mod_timer(&local->dynamic_ps_timer, jiffies +
2299                   msecs_to_jiffies(
2300                   local->hw.conf.dynamic_ps_timeout));
2301         } else {
2302             ieee80211_send_nullfunc(local, sdata, true);
2303             /* Flush to get the tx status of nullfunc frame */
2304             ieee80211_flush_queues(local, sdata, false);
2305         }
2306     }
2307 
2308     if (!(ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS) &&
2309           ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK)) ||
2310         (ifmgd->flags & IEEE80211_STA_NULLFUNC_ACKED)) {
2311         ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED;
2312         local->hw.conf.flags |= IEEE80211_CONF_PS;
2313         ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
2314     }
2315 }
2316 
2317 void ieee80211_dynamic_ps_timer(struct timer_list *t)
2318 {
2319     struct ieee80211_local *local = from_timer(local, t, dynamic_ps_timer);
2320 
2321     ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work);
2322 }
2323 
2324 void ieee80211_dfs_cac_timer_work(struct work_struct *work)
2325 {
2326     struct delayed_work *delayed_work = to_delayed_work(work);
2327     struct ieee80211_link_data *link =
2328         container_of(delayed_work, struct ieee80211_link_data,
2329                  dfs_cac_timer_work);
2330     struct cfg80211_chan_def chandef = link->conf->chandef;
2331     struct ieee80211_sub_if_data *sdata = link->sdata;
2332 
2333     mutex_lock(&sdata->local->mtx);
2334     if (sdata->wdev.cac_started) {
2335         ieee80211_link_release_channel(link);
2336         cfg80211_cac_event(sdata->dev, &chandef,
2337                    NL80211_RADAR_CAC_FINISHED,
2338                    GFP_KERNEL);
2339     }
2340     mutex_unlock(&sdata->local->mtx);
2341 }
2342 
2343 static bool
2344 __ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata)
2345 {
2346     struct ieee80211_local *local = sdata->local;
2347     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2348     bool ret = false;
2349     int ac;
2350 
2351     if (local->hw.queues < IEEE80211_NUM_ACS)
2352         return false;
2353 
2354     for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
2355         struct ieee80211_sta_tx_tspec *tx_tspec = &ifmgd->tx_tspec[ac];
2356         int non_acm_ac;
2357         unsigned long now = jiffies;
2358 
2359         if (tx_tspec->action == TX_TSPEC_ACTION_NONE &&
2360             tx_tspec->admitted_time &&
2361             time_after(now, tx_tspec->time_slice_start + HZ)) {
2362             tx_tspec->consumed_tx_time = 0;
2363             tx_tspec->time_slice_start = now;
2364 
2365             if (tx_tspec->downgraded)
2366                 tx_tspec->action =
2367                     TX_TSPEC_ACTION_STOP_DOWNGRADE;
2368         }
2369 
2370         switch (tx_tspec->action) {
2371         case TX_TSPEC_ACTION_STOP_DOWNGRADE:
2372             /* take the original parameters */
2373             if (drv_conf_tx(local, &sdata->deflink, ac,
2374                     &sdata->deflink.tx_conf[ac]))
2375                 link_err(&sdata->deflink,
2376                      "failed to set TX queue parameters for queue %d\n",
2377                      ac);
2378             tx_tspec->action = TX_TSPEC_ACTION_NONE;
2379             tx_tspec->downgraded = false;
2380             ret = true;
2381             break;
2382         case TX_TSPEC_ACTION_DOWNGRADE:
2383             if (time_after(now, tx_tspec->time_slice_start + HZ)) {
2384                 tx_tspec->action = TX_TSPEC_ACTION_NONE;
2385                 ret = true;
2386                 break;
2387             }
2388             /* downgrade next lower non-ACM AC */
2389             for (non_acm_ac = ac + 1;
2390                  non_acm_ac < IEEE80211_NUM_ACS;
2391                  non_acm_ac++)
2392                 if (!(sdata->wmm_acm & BIT(7 - 2 * non_acm_ac)))
2393                     break;
2394             /* Usually the loop will result in using BK even if it
2395              * requires admission control, but such a configuration
2396              * makes no sense and we have to transmit somehow - the
2397              * AC selection does the same thing.
2398              * If we started out trying to downgrade from BK, then
2399              * the extra condition here might be needed.
2400              */
2401             if (non_acm_ac >= IEEE80211_NUM_ACS)
2402                 non_acm_ac = IEEE80211_AC_BK;
2403             if (drv_conf_tx(local, &sdata->deflink, ac,
2404                     &sdata->deflink.tx_conf[non_acm_ac]))
2405                 link_err(&sdata->deflink,
2406                      "failed to set TX queue parameters for queue %d\n",
2407                      ac);
2408             tx_tspec->action = TX_TSPEC_ACTION_NONE;
2409             ret = true;
2410             schedule_delayed_work(&ifmgd->tx_tspec_wk,
2411                 tx_tspec->time_slice_start + HZ - now + 1);
2412             break;
2413         case TX_TSPEC_ACTION_NONE:
2414             /* nothing now */
2415             break;
2416         }
2417     }
2418 
2419     return ret;
2420 }
2421 
2422 void ieee80211_sta_handle_tspec_ac_params(struct ieee80211_sub_if_data *sdata)
2423 {
2424     if (__ieee80211_sta_handle_tspec_ac_params(sdata))
2425         ieee80211_link_info_change_notify(sdata, &sdata->deflink,
2426                           BSS_CHANGED_QOS);
2427 }
2428 
2429 static void ieee80211_sta_handle_tspec_ac_params_wk(struct work_struct *work)
2430 {
2431     struct ieee80211_sub_if_data *sdata;
2432 
2433     sdata = container_of(work, struct ieee80211_sub_if_data,
2434                  u.mgd.tx_tspec_wk.work);
2435     ieee80211_sta_handle_tspec_ac_params(sdata);
2436 }
2437 
2438 /* MLME */
2439 static bool
2440 ieee80211_sta_wmm_params(struct ieee80211_local *local,
2441              struct ieee80211_link_data *link,
2442              const u8 *wmm_param, size_t wmm_param_len,
2443              const struct ieee80211_mu_edca_param_set *mu_edca)
2444 {
2445     struct ieee80211_sub_if_data *sdata = link->sdata;
2446     struct ieee80211_tx_queue_params params[IEEE80211_NUM_ACS];
2447     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2448     size_t left;
2449     int count, mu_edca_count, ac;
2450     const u8 *pos;
2451     u8 uapsd_queues = 0;
2452 
2453     if (!local->ops->conf_tx)
2454         return false;
2455 
2456     if (local->hw.queues < IEEE80211_NUM_ACS)
2457         return false;
2458 
2459     if (!wmm_param)
2460         return false;
2461 
2462     if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
2463         return false;
2464 
2465     if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
2466         uapsd_queues = ifmgd->uapsd_queues;
2467 
2468     count = wmm_param[6] & 0x0f;
2469     /* -1 is the initial value of ifmgd->mu_edca_last_param_set.
2470      * if mu_edca was preset before and now it disappeared tell
2471      * the driver about it.
2472      */
2473     mu_edca_count = mu_edca ? mu_edca->mu_qos_info & 0x0f : -1;
2474     if (count == link->u.mgd.wmm_last_param_set &&
2475         mu_edca_count == link->u.mgd.mu_edca_last_param_set)
2476         return false;
2477     link->u.mgd.wmm_last_param_set = count;
2478     link->u.mgd.mu_edca_last_param_set = mu_edca_count;
2479 
2480     pos = wmm_param + 8;
2481     left = wmm_param_len - 8;
2482 
2483     memset(&params, 0, sizeof(params));
2484 
2485     sdata->wmm_acm = 0;
2486     for (; left >= 4; left -= 4, pos += 4) {
2487         int aci = (pos[0] >> 5) & 0x03;
2488         int acm = (pos[0] >> 4) & 0x01;
2489         bool uapsd = false;
2490 
2491         switch (aci) {
2492         case 1: /* AC_BK */
2493             ac = IEEE80211_AC_BK;
2494             if (acm)
2495                 sdata->wmm_acm |= BIT(1) | BIT(2); /* BK/- */
2496             if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
2497                 uapsd = true;
2498             params[ac].mu_edca = !!mu_edca;
2499             if (mu_edca)
2500                 params[ac].mu_edca_param_rec = mu_edca->ac_bk;
2501             break;
2502         case 2: /* AC_VI */
2503             ac = IEEE80211_AC_VI;
2504             if (acm)
2505                 sdata->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
2506             if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
2507                 uapsd = true;
2508             params[ac].mu_edca = !!mu_edca;
2509             if (mu_edca)
2510                 params[ac].mu_edca_param_rec = mu_edca->ac_vi;
2511             break;
2512         case 3: /* AC_VO */
2513             ac = IEEE80211_AC_VO;
2514             if (acm)
2515                 sdata->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
2516             if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
2517                 uapsd = true;
2518             params[ac].mu_edca = !!mu_edca;
2519             if (mu_edca)
2520                 params[ac].mu_edca_param_rec = mu_edca->ac_vo;
2521             break;
2522         case 0: /* AC_BE */
2523         default:
2524             ac = IEEE80211_AC_BE;
2525             if (acm)
2526                 sdata->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
2527             if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
2528                 uapsd = true;
2529             params[ac].mu_edca = !!mu_edca;
2530             if (mu_edca)
2531                 params[ac].mu_edca_param_rec = mu_edca->ac_be;
2532             break;
2533         }
2534 
2535         params[ac].aifs = pos[0] & 0x0f;
2536 
2537         if (params[ac].aifs < 2) {
2538             sdata_info(sdata,
2539                    "AP has invalid WMM params (AIFSN=%d for ACI %d), will use 2\n",
2540                    params[ac].aifs, aci);
2541             params[ac].aifs = 2;
2542         }
2543         params[ac].cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
2544         params[ac].cw_min = ecw2cw(pos[1] & 0x0f);
2545         params[ac].txop = get_unaligned_le16(pos + 2);
2546         params[ac].acm = acm;
2547         params[ac].uapsd = uapsd;
2548 
2549         if (params[ac].cw_min == 0 ||
2550             params[ac].cw_min > params[ac].cw_max) {
2551             sdata_info(sdata,
2552                    "AP has invalid WMM params (CWmin/max=%d/%d for ACI %d), using defaults\n",
2553                    params[ac].cw_min, params[ac].cw_max, aci);
2554             return false;
2555         }
2556         ieee80211_regulatory_limit_wmm_params(sdata, &params[ac], ac);
2557     }
2558 
2559     /* WMM specification requires all 4 ACIs. */
2560     for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
2561         if (params[ac].cw_min == 0) {
2562             sdata_info(sdata,
2563                    "AP has invalid WMM params (missing AC %d), using defaults\n",
2564                    ac);
2565             return false;
2566         }
2567     }
2568 
2569     for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
2570         mlme_dbg(sdata,
2571              "WMM AC=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d, downgraded=%d\n",
2572              ac, params[ac].acm,
2573              params[ac].aifs, params[ac].cw_min, params[ac].cw_max,
2574              params[ac].txop, params[ac].uapsd,
2575              ifmgd->tx_tspec[ac].downgraded);
2576         link->tx_conf[ac] = params[ac];
2577         if (!ifmgd->tx_tspec[ac].downgraded &&
2578             drv_conf_tx(local, link, ac, &params[ac]))
2579             link_err(link,
2580                  "failed to set TX queue parameters for AC %d\n",
2581                  ac);
2582     }
2583 
2584     /* enable WMM or activate new settings */
2585     link->conf->qos = true;
2586     return true;
2587 }
2588 
2589 static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
2590 {
2591     lockdep_assert_held(&sdata->local->mtx);
2592 
2593     sdata->u.mgd.flags &= ~IEEE80211_STA_CONNECTION_POLL;
2594     ieee80211_run_deferred_scan(sdata->local);
2595 }
2596 
2597 static void ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
2598 {
2599     mutex_lock(&sdata->local->mtx);
2600     __ieee80211_stop_poll(sdata);
2601     mutex_unlock(&sdata->local->mtx);
2602 }
2603 
2604 static u32 ieee80211_handle_bss_capability(struct ieee80211_link_data *link,
2605                        u16 capab, bool erp_valid, u8 erp)
2606 {
2607     struct ieee80211_bss_conf *bss_conf = link->conf;
2608     struct ieee80211_supported_band *sband;
2609     u32 changed = 0;
2610     bool use_protection;
2611     bool use_short_preamble;
2612     bool use_short_slot;
2613 
2614     sband = ieee80211_get_link_sband(link);
2615     if (!sband)
2616         return changed;
2617 
2618     if (erp_valid) {
2619         use_protection = (erp & WLAN_ERP_USE_PROTECTION) != 0;
2620         use_short_preamble = (erp & WLAN_ERP_BARKER_PREAMBLE) == 0;
2621     } else {
2622         use_protection = false;
2623         use_short_preamble = !!(capab & WLAN_CAPABILITY_SHORT_PREAMBLE);
2624     }
2625 
2626     use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
2627     if (sband->band == NL80211_BAND_5GHZ ||
2628         sband->band == NL80211_BAND_6GHZ)
2629         use_short_slot = true;
2630 
2631     if (use_protection != bss_conf->use_cts_prot) {
2632         bss_conf->use_cts_prot = use_protection;
2633         changed |= BSS_CHANGED_ERP_CTS_PROT;
2634     }
2635 
2636     if (use_short_preamble != bss_conf->use_short_preamble) {
2637         bss_conf->use_short_preamble = use_short_preamble;
2638         changed |= BSS_CHANGED_ERP_PREAMBLE;
2639     }
2640 
2641     if (use_short_slot != bss_conf->use_short_slot) {
2642         bss_conf->use_short_slot = use_short_slot;
2643         changed |= BSS_CHANGED_ERP_SLOT;
2644     }
2645 
2646     return changed;
2647 }
2648 
2649 static u32 ieee80211_link_set_associated(struct ieee80211_link_data *link,
2650                      struct cfg80211_bss *cbss)
2651 {
2652     struct ieee80211_sub_if_data *sdata = link->sdata;
2653     struct ieee80211_bss_conf *bss_conf = link->conf;
2654     struct ieee80211_bss *bss = (void *)cbss->priv;
2655     u32 changed = BSS_CHANGED_QOS;
2656 
2657     /* not really used in MLO */
2658     sdata->u.mgd.beacon_timeout =
2659         usecs_to_jiffies(ieee80211_tu_to_usec(beacon_loss_count *
2660                               bss_conf->beacon_int));
2661 
2662     changed |= ieee80211_handle_bss_capability(link,
2663                            bss_conf->assoc_capability,
2664                            bss->has_erp_value,
2665                            bss->erp_value);
2666 
2667     ieee80211_check_rate_mask(link);
2668 
2669     link->u.mgd.bss = cbss;
2670     memcpy(link->u.mgd.bssid, cbss->bssid, ETH_ALEN);
2671 
2672     if (sdata->vif.p2p ||
2673         sdata->vif.driver_flags & IEEE80211_VIF_GET_NOA_UPDATE) {
2674         const struct cfg80211_bss_ies *ies;
2675 
2676         rcu_read_lock();
2677         ies = rcu_dereference(cbss->ies);
2678         if (ies) {
2679             int ret;
2680 
2681             ret = cfg80211_get_p2p_attr(
2682                     ies->data, ies->len,
2683                     IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
2684                     (u8 *) &bss_conf->p2p_noa_attr,
2685                     sizeof(bss_conf->p2p_noa_attr));
2686             if (ret >= 2) {
2687                 link->u.mgd.p2p_noa_index =
2688                     bss_conf->p2p_noa_attr.index;
2689                 changed |= BSS_CHANGED_P2P_PS;
2690             }
2691         }
2692         rcu_read_unlock();
2693     }
2694 
2695     if (link->u.mgd.have_beacon) {
2696         /*
2697          * If the AP is buggy we may get here with no DTIM period
2698          * known, so assume it's 1 which is the only safe assumption
2699          * in that case, although if the TIM IE is broken powersave
2700          * probably just won't work at all.
2701          */
2702         bss_conf->dtim_period = link->u.mgd.dtim_period ?: 1;
2703         bss_conf->beacon_rate = bss->beacon_rate;
2704         changed |= BSS_CHANGED_BEACON_INFO;
2705     } else {
2706         bss_conf->beacon_rate = NULL;
2707         bss_conf->dtim_period = 0;
2708     }
2709 
2710     /* Tell the driver to monitor connection quality (if supported) */
2711     if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI &&
2712         bss_conf->cqm_rssi_thold)
2713         changed |= BSS_CHANGED_CQM;
2714 
2715     return changed;
2716 }
2717 
2718 static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
2719                      struct ieee80211_mgd_assoc_data *assoc_data,
2720                      u64 changed[IEEE80211_MLD_MAX_NUM_LINKS])
2721 {
2722     struct ieee80211_local *local = sdata->local;
2723     struct ieee80211_vif_cfg *vif_cfg = &sdata->vif.cfg;
2724     u64 vif_changed = BSS_CHANGED_ASSOC;
2725     unsigned int link_id;
2726 
2727     sdata->u.mgd.associated = true;
2728 
2729     for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
2730         struct cfg80211_bss *cbss = assoc_data->link[link_id].bss;
2731         struct ieee80211_link_data *link;
2732 
2733         if (!cbss)
2734             continue;
2735 
2736         link = sdata_dereference(sdata->link[link_id], sdata);
2737         if (WARN_ON(!link))
2738             return;
2739 
2740         changed[link_id] |= ieee80211_link_set_associated(link, cbss);
2741     }
2742 
2743     /* just to be sure */
2744     ieee80211_stop_poll(sdata);
2745 
2746     ieee80211_led_assoc(local, 1);
2747 
2748     vif_cfg->assoc = 1;
2749 
2750     /* Enable ARP filtering */
2751     if (vif_cfg->arp_addr_cnt)
2752         vif_changed |= BSS_CHANGED_ARP_FILTER;
2753 
2754     if (sdata->vif.valid_links) {
2755         for (link_id = 0;
2756              link_id < IEEE80211_MLD_MAX_NUM_LINKS;
2757              link_id++) {
2758             struct ieee80211_link_data *link;
2759             struct cfg80211_bss *cbss = assoc_data->link[link_id].bss;
2760 
2761             if (!cbss)
2762                 continue;
2763 
2764             link = sdata_dereference(sdata->link[link_id], sdata);
2765             if (WARN_ON(!link))
2766                 return;
2767 
2768             ieee80211_link_info_change_notify(sdata, link,
2769                               changed[link_id]);
2770 
2771             ieee80211_recalc_smps(sdata, link);
2772         }
2773 
2774         ieee80211_vif_cfg_change_notify(sdata, vif_changed);
2775     } else {
2776         ieee80211_bss_info_change_notify(sdata,
2777                          vif_changed | changed[0]);
2778     }
2779 
2780     mutex_lock(&local->iflist_mtx);
2781     ieee80211_recalc_ps(local);
2782     mutex_unlock(&local->iflist_mtx);
2783 
2784     /* leave this here to not change ordering in non-MLO cases */
2785     if (!sdata->vif.valid_links)
2786         ieee80211_recalc_smps(sdata, &sdata->deflink);
2787     ieee80211_recalc_ps_vif(sdata);
2788 
2789     netif_carrier_on(sdata->dev);
2790 }
2791 
2792 static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
2793                    u16 stype, u16 reason, bool tx,
2794                    u8 *frame_buf)
2795 {
2796     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2797     struct ieee80211_local *local = sdata->local;
2798     unsigned int link_id;
2799     u32 changed = 0;
2800     struct ieee80211_prep_tx_info info = {
2801         .subtype = stype,
2802     };
2803 
2804     sdata_assert_lock(sdata);
2805 
2806     if (WARN_ON_ONCE(tx && !frame_buf))
2807         return;
2808 
2809     if (WARN_ON(!ifmgd->associated))
2810         return;
2811 
2812     ieee80211_stop_poll(sdata);
2813 
2814     ifmgd->associated = false;
2815 
2816     /* other links will be destroyed */
2817     sdata->deflink.u.mgd.bss = NULL;
2818 
2819     netif_carrier_off(sdata->dev);
2820 
2821     /*
2822      * if we want to get out of ps before disassoc (why?) we have
2823      * to do it before sending disassoc, as otherwise the null-packet
2824      * won't be valid.
2825      */
2826     if (local->hw.conf.flags & IEEE80211_CONF_PS) {
2827         local->hw.conf.flags &= ~IEEE80211_CONF_PS;
2828         ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
2829     }
2830     local->ps_sdata = NULL;
2831 
2832     /* disable per-vif ps */
2833     ieee80211_recalc_ps_vif(sdata);
2834 
2835     /* make sure ongoing transmission finishes */
2836     synchronize_net();
2837 
2838     /*
2839      * drop any frame before deauth/disassoc, this can be data or
2840      * management frame. Since we are disconnecting, we should not
2841      * insist sending these frames which can take time and delay
2842      * the disconnection and possible the roaming.
2843      */
2844     if (tx)
2845         ieee80211_flush_queues(local, sdata, true);
2846 
2847     /* deauthenticate/disassociate now */
2848     if (tx || frame_buf) {
2849         /*
2850          * In multi channel scenarios guarantee that the virtual
2851          * interface is granted immediate airtime to transmit the
2852          * deauthentication frame by calling mgd_prepare_tx, if the
2853          * driver requested so.
2854          */
2855         if (ieee80211_hw_check(&local->hw, DEAUTH_NEED_MGD_TX_PREP) &&
2856             !sdata->deflink.u.mgd.have_beacon) {
2857             drv_mgd_prepare_tx(sdata->local, sdata, &info);
2858         }
2859 
2860         ieee80211_send_deauth_disassoc(sdata, sdata->vif.cfg.ap_addr,
2861                            sdata->vif.cfg.ap_addr, stype,
2862                            reason, tx, frame_buf);
2863     }
2864 
2865     /* flush out frame - make sure the deauth was actually sent */
2866     if (tx)
2867         ieee80211_flush_queues(local, sdata, false);
2868 
2869     drv_mgd_complete_tx(sdata->local, sdata, &info);
2870 
2871     /* clear AP addr only after building the needed mgmt frames */
2872     eth_zero_addr(sdata->deflink.u.mgd.bssid);
2873     eth_zero_addr(sdata->vif.cfg.ap_addr);
2874 
2875     sdata->vif.cfg.ssid_len = 0;
2876 
2877     /* remove AP and TDLS peers */
2878     sta_info_flush(sdata);
2879 
2880     /* finally reset all BSS / config parameters */
2881     if (!sdata->vif.valid_links)
2882         changed |= ieee80211_reset_erp_info(sdata);
2883 
2884     ieee80211_led_assoc(local, 0);
2885     changed |= BSS_CHANGED_ASSOC;
2886     sdata->vif.cfg.assoc = false;
2887 
2888     sdata->deflink.u.mgd.p2p_noa_index = -1;
2889     memset(&sdata->vif.bss_conf.p2p_noa_attr, 0,
2890            sizeof(sdata->vif.bss_conf.p2p_noa_attr));
2891 
2892     /* on the next assoc, re-program HT/VHT parameters */
2893     memset(&ifmgd->ht_capa, 0, sizeof(ifmgd->ht_capa));
2894     memset(&ifmgd->ht_capa_mask, 0, sizeof(ifmgd->ht_capa_mask));
2895     memset(&ifmgd->vht_capa, 0, sizeof(ifmgd->vht_capa));
2896     memset(&ifmgd->vht_capa_mask, 0, sizeof(ifmgd->vht_capa_mask));
2897 
2898     /*
2899      * reset MU-MIMO ownership and group data in default link,
2900      * if used, other links are destroyed
2901      */
2902     memset(sdata->vif.bss_conf.mu_group.membership, 0,
2903            sizeof(sdata->vif.bss_conf.mu_group.membership));
2904     memset(sdata->vif.bss_conf.mu_group.position, 0,
2905            sizeof(sdata->vif.bss_conf.mu_group.position));
2906     if (!sdata->vif.valid_links)
2907         changed |= BSS_CHANGED_MU_GROUPS;
2908     sdata->vif.bss_conf.mu_mimo_owner = false;
2909 
2910     sdata->deflink.ap_power_level = IEEE80211_UNSET_POWER_LEVEL;
2911 
2912     del_timer_sync(&local->dynamic_ps_timer);
2913     cancel_work_sync(&local->dynamic_ps_enable_work);
2914 
2915     /* Disable ARP filtering */
2916     if (sdata->vif.cfg.arp_addr_cnt)
2917         changed |= BSS_CHANGED_ARP_FILTER;
2918 
2919     sdata->vif.bss_conf.qos = false;
2920     if (!sdata->vif.valid_links) {
2921         changed |= BSS_CHANGED_QOS;
2922         /* The BSSID (not really interesting) and HT changed */
2923         changed |= BSS_CHANGED_BSSID | BSS_CHANGED_HT;
2924         ieee80211_bss_info_change_notify(sdata, changed);
2925     } else {
2926         ieee80211_vif_cfg_change_notify(sdata, changed);
2927     }
2928 
2929     /* disassociated - set to defaults now */
2930     ieee80211_set_wmm_default(&sdata->deflink, false, false);
2931 
2932     del_timer_sync(&sdata->u.mgd.conn_mon_timer);
2933     del_timer_sync(&sdata->u.mgd.bcn_mon_timer);
2934     del_timer_sync(&sdata->u.mgd.timer);
2935     del_timer_sync(&sdata->deflink.u.mgd.chswitch_timer);
2936 
2937     sdata->vif.bss_conf.dtim_period = 0;
2938     sdata->vif.bss_conf.beacon_rate = NULL;
2939 
2940     sdata->deflink.u.mgd.have_beacon = false;
2941     sdata->deflink.u.mgd.tracking_signal_avg = false;
2942     sdata->deflink.u.mgd.disable_wmm_tracking = false;
2943 
2944     ifmgd->flags = 0;
2945     sdata->deflink.u.mgd.conn_flags = 0;
2946     mutex_lock(&local->mtx);
2947 
2948     for (link_id = 0; link_id < ARRAY_SIZE(sdata->link); link_id++) {
2949         struct ieee80211_link_data *link;
2950 
2951         link = sdata_dereference(sdata->link[link_id], sdata);
2952         if (!link)
2953             continue;
2954         ieee80211_link_release_channel(link);
2955     }
2956 
2957     sdata->vif.bss_conf.csa_active = false;
2958     sdata->deflink.u.mgd.csa_waiting_bcn = false;
2959     sdata->deflink.u.mgd.csa_ignored_same_chan = false;
2960     if (sdata->deflink.csa_block_tx) {
2961         ieee80211_wake_vif_queues(local, sdata,
2962                       IEEE80211_QUEUE_STOP_REASON_CSA);
2963         sdata->deflink.csa_block_tx = false;
2964     }
2965     mutex_unlock(&local->mtx);
2966 
2967     /* existing TX TSPEC sessions no longer exist */
2968     memset(ifmgd->tx_tspec, 0, sizeof(ifmgd->tx_tspec));
2969     cancel_delayed_work_sync(&ifmgd->tx_tspec_wk);
2970 
2971     sdata->vif.bss_conf.pwr_reduction = 0;
2972     sdata->vif.bss_conf.tx_pwr_env_num = 0;
2973     memset(sdata->vif.bss_conf.tx_pwr_env, 0,
2974            sizeof(sdata->vif.bss_conf.tx_pwr_env));
2975 
2976     ieee80211_vif_set_links(sdata, 0);
2977 }
2978 
2979 static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
2980 {
2981     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2982     struct ieee80211_local *local = sdata->local;
2983 
2984     mutex_lock(&local->mtx);
2985     if (!(ifmgd->flags & IEEE80211_STA_CONNECTION_POLL))
2986         goto out;
2987 
2988     __ieee80211_stop_poll(sdata);
2989 
2990     mutex_lock(&local->iflist_mtx);
2991     ieee80211_recalc_ps(local);
2992     mutex_unlock(&local->iflist_mtx);
2993 
2994     if (ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
2995         goto out;
2996 
2997     /*
2998      * We've received a probe response, but are not sure whether
2999      * we have or will be receiving any beacons or data, so let's
3000      * schedule the timers again, just in case.
3001      */
3002     ieee80211_sta_reset_beacon_monitor(sdata);
3003 
3004     mod_timer(&ifmgd->conn_mon_timer,
3005           round_jiffies_up(jiffies +
3006                    IEEE80211_CONNECTION_IDLE_TIME));
3007 out:
3008     mutex_unlock(&local->mtx);
3009 }
3010 
3011 static void ieee80211_sta_tx_wmm_ac_notify(struct ieee80211_sub_if_data *sdata,
3012                        struct ieee80211_hdr *hdr,
3013                        u16 tx_time)
3014 {
3015     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3016     u16 tid;
3017     int ac;
3018     struct ieee80211_sta_tx_tspec *tx_tspec;
3019     unsigned long now = jiffies;
3020 
3021     if (!ieee80211_is_data_qos(hdr->frame_control))
3022         return;
3023 
3024     tid = ieee80211_get_tid(hdr);
3025     ac = ieee80211_ac_from_tid(tid);
3026     tx_tspec = &ifmgd->tx_tspec[ac];
3027 
3028     if (likely(!tx_tspec->admitted_time))
3029         return;
3030 
3031     if (time_after(now, tx_tspec->time_slice_start + HZ)) {
3032         tx_tspec->consumed_tx_time = 0;
3033         tx_tspec->time_slice_start = now;
3034 
3035         if (tx_tspec->downgraded) {
3036             tx_tspec->action = TX_TSPEC_ACTION_STOP_DOWNGRADE;
3037             schedule_delayed_work(&ifmgd->tx_tspec_wk, 0);
3038         }
3039     }
3040 
3041     if (tx_tspec->downgraded)
3042         return;
3043 
3044     tx_tspec->consumed_tx_time += tx_time;
3045 
3046     if (tx_tspec->consumed_tx_time >= tx_tspec->admitted_time) {
3047         tx_tspec->downgraded = true;
3048         tx_tspec->action = TX_TSPEC_ACTION_DOWNGRADE;
3049         schedule_delayed_work(&ifmgd->tx_tspec_wk, 0);
3050     }
3051 }
3052 
3053 void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
3054                  struct ieee80211_hdr *hdr, bool ack, u16 tx_time)
3055 {
3056     ieee80211_sta_tx_wmm_ac_notify(sdata, hdr, tx_time);
3057 
3058     if (!ieee80211_is_any_nullfunc(hdr->frame_control) ||
3059         !sdata->u.mgd.probe_send_count)
3060         return;
3061 
3062     if (ack)
3063         sdata->u.mgd.probe_send_count = 0;
3064     else
3065         sdata->u.mgd.nullfunc_failed = true;
3066     ieee80211_queue_work(&sdata->local->hw, &sdata->work);
3067 }
3068 
3069 static void ieee80211_mlme_send_probe_req(struct ieee80211_sub_if_data *sdata,
3070                       const u8 *src, const u8 *dst,
3071                       const u8 *ssid, size_t ssid_len,
3072                       struct ieee80211_channel *channel)
3073 {
3074     struct sk_buff *skb;
3075 
3076     skb = ieee80211_build_probe_req(sdata, src, dst, (u32)-1, channel,
3077                     ssid, ssid_len, NULL, 0,
3078                     IEEE80211_PROBE_FLAG_DIRECTED);
3079     if (skb)
3080         ieee80211_tx_skb(sdata, skb);
3081 }
3082 
3083 static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
3084 {
3085     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3086     u8 *dst = sdata->vif.cfg.ap_addr;
3087     u8 unicast_limit = max(1, max_probe_tries - 3);
3088     struct sta_info *sta;
3089 
3090     if (WARN_ON(sdata->vif.valid_links))
3091         return;
3092 
3093     /*
3094      * Try sending broadcast probe requests for the last three
3095      * probe requests after the first ones failed since some
3096      * buggy APs only support broadcast probe requests.
3097      */
3098     if (ifmgd->probe_send_count >= unicast_limit)
3099         dst = NULL;
3100 
3101     /*
3102      * When the hardware reports an accurate Tx ACK status, it's
3103      * better to send a nullfunc frame instead of a probe request,
3104      * as it will kick us off the AP quickly if we aren't associated
3105      * anymore. The timeout will be reset if the frame is ACKed by
3106      * the AP.
3107      */
3108     ifmgd->probe_send_count++;
3109 
3110     if (dst) {
3111         mutex_lock(&sdata->local->sta_mtx);
3112         sta = sta_info_get(sdata, dst);
3113         if (!WARN_ON(!sta))
3114             ieee80211_check_fast_rx(sta);
3115         mutex_unlock(&sdata->local->sta_mtx);
3116     }
3117 
3118     if (ieee80211_hw_check(&sdata->local->hw, REPORTS_TX_ACK_STATUS)) {
3119         ifmgd->nullfunc_failed = false;
3120         ieee80211_send_nullfunc(sdata->local, sdata, false);
3121     } else {
3122         ieee80211_mlme_send_probe_req(sdata, sdata->vif.addr, dst,
3123                           sdata->vif.cfg.ssid,
3124                           sdata->vif.cfg.ssid_len,
3125                           sdata->deflink.u.mgd.bss->channel);
3126     }
3127 
3128     ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
3129     run_again(sdata, ifmgd->probe_timeout);
3130 }
3131 
3132 static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
3133                    bool beacon)
3134 {
3135     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3136     bool already = false;
3137 
3138     if (WARN_ON(sdata->vif.valid_links))
3139         return;
3140 
3141     if (!ieee80211_sdata_running(sdata))
3142         return;
3143 
3144     sdata_lock(sdata);
3145 
3146     if (!ifmgd->associated)
3147         goto out;
3148 
3149     mutex_lock(&sdata->local->mtx);
3150 
3151     if (sdata->local->tmp_channel || sdata->local->scanning) {
3152         mutex_unlock(&sdata->local->mtx);
3153         goto out;
3154     }
3155 
3156     if (sdata->local->suspending) {
3157         /* reschedule after resume */
3158         mutex_unlock(&sdata->local->mtx);
3159         ieee80211_reset_ap_probe(sdata);
3160         goto out;
3161     }
3162 
3163     if (beacon) {
3164         mlme_dbg_ratelimited(sdata,
3165                      "detected beacon loss from AP (missed %d beacons) - probing\n",
3166                      beacon_loss_count);
3167 
3168         ieee80211_cqm_beacon_loss_notify(&sdata->vif, GFP_KERNEL);
3169     }
3170 
3171     /*
3172      * The driver/our work has already reported this event or the
3173      * connection monitoring has kicked in and we have already sent
3174      * a probe request. Or maybe the AP died and the driver keeps
3175      * reporting until we disassociate...
3176      *
3177      * In either case we have to ignore the current call to this
3178      * function (except for setting the correct probe reason bit)
3179      * because otherwise we would reset the timer every time and
3180      * never check whether we received a probe response!
3181      */
3182     if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL)
3183         already = true;
3184 
3185     ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL;
3186 
3187     mutex_unlock(&sdata->local->mtx);
3188 
3189     if (already)
3190         goto out;
3191 
3192     mutex_lock(&sdata->local->iflist_mtx);
3193     ieee80211_recalc_ps(sdata->local);
3194     mutex_unlock(&sdata->local->iflist_mtx);
3195 
3196     ifmgd->probe_send_count = 0;
3197     ieee80211_mgd_probe_ap_send(sdata);
3198  out:
3199     sdata_unlock(sdata);
3200 }
3201 
3202 struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
3203                       struct ieee80211_vif *vif)
3204 {
3205     struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
3206     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3207     struct cfg80211_bss *cbss;
3208     struct sk_buff *skb;
3209     const struct element *ssid;
3210     int ssid_len;
3211 
3212     if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
3213             sdata->vif.valid_links))
3214         return NULL;
3215 
3216     sdata_assert_lock(sdata);
3217 
3218     if (ifmgd->associated)
3219         cbss = sdata->deflink.u.mgd.bss;
3220     else if (ifmgd->auth_data)
3221         cbss = ifmgd->auth_data->bss;
3222     else if (ifmgd->assoc_data && ifmgd->assoc_data->link[0].bss)
3223         cbss = ifmgd->assoc_data->link[0].bss;
3224     else
3225         return NULL;
3226 
3227     rcu_read_lock();
3228     ssid = ieee80211_bss_get_elem(cbss, WLAN_EID_SSID);
3229     if (WARN_ONCE(!ssid || ssid->datalen > IEEE80211_MAX_SSID_LEN,
3230               "invalid SSID element (len=%d)",
3231               ssid ? ssid->datalen : -1))
3232         ssid_len = 0;
3233     else
3234         ssid_len = ssid->datalen;
3235 
3236     skb = ieee80211_build_probe_req(sdata, sdata->vif.addr, cbss->bssid,
3237                     (u32) -1, cbss->channel,
3238                     ssid->data, ssid_len,
3239                     NULL, 0, IEEE80211_PROBE_FLAG_DIRECTED);
3240     rcu_read_unlock();
3241 
3242     return skb;
3243 }
3244 EXPORT_SYMBOL(ieee80211_ap_probereq_get);
3245 
3246 static void ieee80211_report_disconnect(struct ieee80211_sub_if_data *sdata,
3247                     const u8 *buf, size_t len, bool tx,
3248                     u16 reason, bool reconnect)
3249 {
3250     struct ieee80211_event event = {
3251         .type = MLME_EVENT,
3252         .u.mlme.data = tx ? DEAUTH_TX_EVENT : DEAUTH_RX_EVENT,
3253         .u.mlme.reason = reason,
3254     };
3255 
3256     if (tx)
3257         cfg80211_tx_mlme_mgmt(sdata->dev, buf, len, reconnect);
3258     else
3259         cfg80211_rx_mlme_mgmt(sdata->dev, buf, len);
3260 
3261     drv_event_callback(sdata->local, sdata, &event);
3262 }
3263 
3264 static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
3265 {
3266     struct ieee80211_local *local = sdata->local;
3267     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3268     u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
3269     bool tx;
3270 
3271     sdata_lock(sdata);
3272     if (!ifmgd->associated) {
3273         sdata_unlock(sdata);
3274         return;
3275     }
3276 
3277     /* in MLO assume we have a link where we can TX the frame */
3278     tx = sdata->vif.valid_links || !sdata->deflink.csa_block_tx;
3279 
3280     if (!ifmgd->driver_disconnect) {
3281         unsigned int link_id;
3282 
3283         /*
3284          * AP is probably out of range (or not reachable for another
3285          * reason) so remove the bss structs for that AP. In the case
3286          * of multi-link, it's not clear that all of them really are
3287          * out of range, but if they weren't the driver likely would
3288          * have switched to just have a single link active?
3289          */
3290         for (link_id = 0;
3291              link_id < ARRAY_SIZE(sdata->link);
3292              link_id++) {
3293             struct ieee80211_link_data *link;
3294 
3295             link = sdata_dereference(sdata->link[link_id], sdata);
3296             if (!link)
3297                 continue;
3298             cfg80211_unlink_bss(local->hw.wiphy, link->u.mgd.bss);
3299             link->u.mgd.bss = NULL;
3300         }
3301     }
3302 
3303     ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
3304                    ifmgd->driver_disconnect ?
3305                     WLAN_REASON_DEAUTH_LEAVING :
3306                     WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
3307                    tx, frame_buf);
3308     mutex_lock(&local->mtx);
3309     /* the other links will be destroyed */
3310     sdata->vif.bss_conf.csa_active = false;
3311     sdata->deflink.u.mgd.csa_waiting_bcn = false;
3312     if (sdata->deflink.csa_block_tx) {
3313         ieee80211_wake_vif_queues(local, sdata,
3314                       IEEE80211_QUEUE_STOP_REASON_CSA);
3315         sdata->deflink.csa_block_tx = false;
3316     }
3317     mutex_unlock(&local->mtx);
3318 
3319     ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), tx,
3320                     WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
3321                     ifmgd->reconnect);
3322     ifmgd->reconnect = false;
3323 
3324     sdata_unlock(sdata);
3325 }
3326 
3327 static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
3328 {
3329     struct ieee80211_sub_if_data *sdata =
3330         container_of(work, struct ieee80211_sub_if_data,
3331                  u.mgd.beacon_connection_loss_work);
3332     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3333 
3334     if (ifmgd->connection_loss) {
3335         sdata_info(sdata, "Connection to AP %pM lost\n",
3336                sdata->vif.cfg.ap_addr);
3337         __ieee80211_disconnect(sdata);
3338         ifmgd->connection_loss = false;
3339     } else if (ifmgd->driver_disconnect) {
3340         sdata_info(sdata,
3341                "Driver requested disconnection from AP %pM\n",
3342                sdata->vif.cfg.ap_addr);
3343         __ieee80211_disconnect(sdata);
3344         ifmgd->driver_disconnect = false;
3345     } else {
3346         if (ifmgd->associated)
3347             sdata->deflink.u.mgd.beacon_loss_count++;
3348         ieee80211_mgd_probe_ap(sdata, true);
3349     }
3350 }
3351 
3352 static void ieee80211_csa_connection_drop_work(struct work_struct *work)
3353 {
3354     struct ieee80211_sub_if_data *sdata =
3355         container_of(work, struct ieee80211_sub_if_data,
3356                  u.mgd.csa_connection_drop_work);
3357 
3358     __ieee80211_disconnect(sdata);
3359 }
3360 
3361 void ieee80211_beacon_loss(struct ieee80211_vif *vif)
3362 {
3363     struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
3364     struct ieee80211_hw *hw = &sdata->local->hw;
3365 
3366     trace_api_beacon_loss(sdata);
3367 
3368     sdata->u.mgd.connection_loss = false;
3369     ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
3370 }
3371 EXPORT_SYMBOL(ieee80211_beacon_loss);
3372 
3373 void ieee80211_connection_loss(struct ieee80211_vif *vif)
3374 {
3375     struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
3376     struct ieee80211_hw *hw = &sdata->local->hw;
3377 
3378     trace_api_connection_loss(sdata);
3379 
3380     sdata->u.mgd.connection_loss = true;
3381     ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
3382 }
3383 EXPORT_SYMBOL(ieee80211_connection_loss);
3384 
3385 void ieee80211_disconnect(struct ieee80211_vif *vif, bool reconnect)
3386 {
3387     struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
3388     struct ieee80211_hw *hw = &sdata->local->hw;
3389 
3390     trace_api_disconnect(sdata, reconnect);
3391 
3392     if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
3393         return;
3394 
3395     sdata->u.mgd.driver_disconnect = true;
3396     sdata->u.mgd.reconnect = reconnect;
3397     ieee80211_queue_work(hw, &sdata->u.mgd.beacon_connection_loss_work);
3398 }
3399 EXPORT_SYMBOL(ieee80211_disconnect);
3400 
3401 static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
3402                     bool assoc)
3403 {
3404     struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
3405 
3406     sdata_assert_lock(sdata);
3407 
3408     if (!assoc) {
3409         /*
3410          * we are not authenticated yet, the only timer that could be
3411          * running is the timeout for the authentication response which
3412          * which is not relevant anymore.
3413          */
3414         del_timer_sync(&sdata->u.mgd.timer);
3415         sta_info_destroy_addr(sdata, auth_data->ap_addr);
3416 
3417         /* other links are destroyed */
3418         sdata->deflink.u.mgd.conn_flags = 0;
3419         eth_zero_addr(sdata->deflink.u.mgd.bssid);
3420         ieee80211_link_info_change_notify(sdata, &sdata->deflink,
3421                           BSS_CHANGED_BSSID);
3422         sdata->u.mgd.flags = 0;
3423 
3424         mutex_lock(&sdata->local->mtx);
3425         ieee80211_link_release_channel(&sdata->deflink);
3426         ieee80211_vif_set_links(sdata, 0);
3427         mutex_unlock(&sdata->local->mtx);
3428     }
3429 
3430     cfg80211_put_bss(sdata->local->hw.wiphy, auth_data->bss);
3431     kfree(auth_data);
3432     sdata->u.mgd.auth_data = NULL;
3433 }
3434 
3435 enum assoc_status {
3436     ASSOC_SUCCESS,
3437     ASSOC_REJECTED,
3438     ASSOC_TIMEOUT,
3439     ASSOC_ABANDON,
3440 };
3441 
3442 static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
3443                      enum assoc_status status)
3444 {
3445     struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
3446 
3447     sdata_assert_lock(sdata);
3448 
3449     if (status != ASSOC_SUCCESS) {
3450         /*
3451          * we are not associated yet, the only timer that could be
3452          * running is the timeout for the association response which
3453          * which is not relevant anymore.
3454          */
3455         del_timer_sync(&sdata->u.mgd.timer);
3456         sta_info_destroy_addr(sdata, assoc_data->ap_addr);
3457 
3458         sdata->deflink.u.mgd.conn_flags = 0;
3459         eth_zero_addr(sdata->deflink.u.mgd.bssid);
3460         ieee80211_link_info_change_notify(sdata, &sdata->deflink,
3461                           BSS_CHANGED_BSSID);
3462         sdata->u.mgd.flags = 0;
3463         sdata->vif.bss_conf.mu_mimo_owner = false;
3464 
3465         if (status != ASSOC_REJECTED) {
3466             struct cfg80211_assoc_failure data = {
3467                 .timeout = status == ASSOC_TIMEOUT,
3468             };
3469             int i;
3470 
3471             BUILD_BUG_ON(ARRAY_SIZE(data.bss) !=
3472                      ARRAY_SIZE(assoc_data->link));
3473 
3474             for (i = 0; i < ARRAY_SIZE(data.bss); i++)
3475                 data.bss[i] = assoc_data->link[i].bss;
3476 
3477             if (sdata->vif.valid_links)
3478                 data.ap_mld_addr = assoc_data->ap_addr;
3479 
3480             cfg80211_assoc_failure(sdata->dev, &data);
3481         }
3482 
3483         mutex_lock(&sdata->local->mtx);
3484         ieee80211_link_release_channel(&sdata->deflink);
3485         ieee80211_vif_set_links(sdata, 0);
3486         mutex_unlock(&sdata->local->mtx);
3487     }
3488 
3489     kfree(assoc_data);
3490     sdata->u.mgd.assoc_data = NULL;
3491 }
3492 
3493 static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
3494                      struct ieee80211_mgmt *mgmt, size_t len)
3495 {
3496     struct ieee80211_local *local = sdata->local;
3497     struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
3498     const struct element *challenge;
3499     u8 *pos;
3500     u32 tx_flags = 0;
3501     struct ieee80211_prep_tx_info info = {
3502         .subtype = IEEE80211_STYPE_AUTH,
3503     };
3504 
3505     pos = mgmt->u.auth.variable;
3506     challenge = cfg80211_find_elem(WLAN_EID_CHALLENGE, pos,
3507                        len - (pos - (u8 *)mgmt));
3508     if (!challenge)
3509         return;
3510     auth_data->expected_transaction = 4;
3511     drv_mgd_prepare_tx(sdata->local, sdata, &info);
3512     if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
3513         tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
3514                IEEE80211_TX_INTFL_MLME_CONN_TX;
3515     ieee80211_send_auth(sdata, 3, auth_data->algorithm, 0,
3516                 (void *)challenge,
3517                 challenge->datalen + sizeof(*challenge),
3518                 auth_data->ap_addr, auth_data->ap_addr,
3519                 auth_data->key, auth_data->key_len,
3520                 auth_data->key_idx, tx_flags);
3521 }
3522 
3523 static bool ieee80211_mark_sta_auth(struct ieee80211_sub_if_data *sdata)
3524 {
3525     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3526     const u8 *ap_addr = ifmgd->auth_data->ap_addr;
3527     struct sta_info *sta;
3528     bool result = true;
3529 
3530     sdata_info(sdata, "authenticated\n");
3531     ifmgd->auth_data->done = true;
3532     ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
3533     ifmgd->auth_data->timeout_started = true;
3534     run_again(sdata, ifmgd->auth_data->timeout);
3535 
3536     /* move station state to auth */
3537     mutex_lock(&sdata->local->sta_mtx);
3538     sta = sta_info_get(sdata, ap_addr);
3539     if (!sta) {
3540         WARN_ONCE(1, "%s: STA %pM not found", sdata->name, ap_addr);
3541         result = false;
3542         goto out;
3543     }
3544     if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) {
3545         sdata_info(sdata, "failed moving %pM to auth\n", ap_addr);
3546         result = false;
3547         goto out;
3548     }
3549 
3550 out:
3551     mutex_unlock(&sdata->local->sta_mtx);
3552     return result;
3553 }
3554 
3555 static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
3556                    struct ieee80211_mgmt *mgmt, size_t len)
3557 {
3558     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3559     u16 auth_alg, auth_transaction, status_code;
3560     struct ieee80211_event event = {
3561         .type = MLME_EVENT,
3562         .u.mlme.data = AUTH_EVENT,
3563     };
3564     struct ieee80211_prep_tx_info info = {
3565         .subtype = IEEE80211_STYPE_AUTH,
3566     };
3567 
3568     sdata_assert_lock(sdata);
3569 
3570     if (len < 24 + 6)
3571         return;
3572 
3573     if (!ifmgd->auth_data || ifmgd->auth_data->done)
3574         return;
3575 
3576     if (!ether_addr_equal(ifmgd->auth_data->ap_addr, mgmt->bssid))
3577         return;
3578 
3579     auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
3580     auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
3581     status_code = le16_to_cpu(mgmt->u.auth.status_code);
3582 
3583     if (auth_alg != ifmgd->auth_data->algorithm ||
3584         (auth_alg != WLAN_AUTH_SAE &&
3585          auth_transaction != ifmgd->auth_data->expected_transaction) ||
3586         (auth_alg == WLAN_AUTH_SAE &&
3587          (auth_transaction < ifmgd->auth_data->expected_transaction ||
3588           auth_transaction > 2))) {
3589         sdata_info(sdata, "%pM unexpected authentication state: alg %d (expected %d) transact %d (expected %d)\n",
3590                mgmt->sa, auth_alg, ifmgd->auth_data->algorithm,
3591                auth_transaction,
3592                ifmgd->auth_data->expected_transaction);
3593         goto notify_driver;
3594     }
3595 
3596     if (status_code != WLAN_STATUS_SUCCESS) {
3597         cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
3598 
3599         if (auth_alg == WLAN_AUTH_SAE &&
3600             (status_code == WLAN_STATUS_ANTI_CLOG_REQUIRED ||
3601              (auth_transaction == 1 &&
3602               (status_code == WLAN_STATUS_SAE_HASH_TO_ELEMENT ||
3603                status_code == WLAN_STATUS_SAE_PK)))) {
3604             /* waiting for userspace now */
3605             ifmgd->auth_data->waiting = true;
3606             ifmgd->auth_data->timeout =
3607                 jiffies + IEEE80211_AUTH_WAIT_SAE_RETRY;
3608             ifmgd->auth_data->timeout_started = true;
3609             run_again(sdata, ifmgd->auth_data->timeout);
3610             goto notify_driver;
3611         }
3612 
3613         sdata_info(sdata, "%pM denied authentication (status %d)\n",
3614                mgmt->sa, status_code);
3615         ieee80211_destroy_auth_data(sdata, false);
3616         event.u.mlme.status = MLME_DENIED;
3617         event.u.mlme.reason = status_code;
3618         drv_event_callback(sdata->local, sdata, &event);
3619         goto notify_driver;
3620     }
3621 
3622     switch (ifmgd->auth_data->algorithm) {
3623     case WLAN_AUTH_OPEN:
3624     case WLAN_AUTH_LEAP:
3625     case WLAN_AUTH_FT:
3626     case WLAN_AUTH_SAE:
3627     case WLAN_AUTH_FILS_SK:
3628     case WLAN_AUTH_FILS_SK_PFS:
3629     case WLAN_AUTH_FILS_PK:
3630         break;
3631     case WLAN_AUTH_SHARED_KEY:
3632         if (ifmgd->auth_data->expected_transaction != 4) {
3633             ieee80211_auth_challenge(sdata, mgmt, len);
3634             /* need another frame */
3635             return;
3636         }
3637         break;
3638     default:
3639         WARN_ONCE(1, "invalid auth alg %d",
3640               ifmgd->auth_data->algorithm);
3641         goto notify_driver;
3642     }
3643 
3644     event.u.mlme.status = MLME_SUCCESS;
3645     info.success = 1;
3646     drv_event_callback(sdata->local, sdata, &event);
3647     if (ifmgd->auth_data->algorithm != WLAN_AUTH_SAE ||
3648         (auth_transaction == 2 &&
3649          ifmgd->auth_data->expected_transaction == 2)) {
3650         if (!ieee80211_mark_sta_auth(sdata))
3651             return; /* ignore frame -- wait for timeout */
3652     } else if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE &&
3653            auth_transaction == 2) {
3654         sdata_info(sdata, "SAE peer confirmed\n");
3655         ifmgd->auth_data->peer_confirmed = true;
3656     }
3657 
3658     cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
3659 notify_driver:
3660     drv_mgd_complete_tx(sdata->local, sdata, &info);
3661 }
3662 
3663 #define case_WLAN(type) \
3664     case WLAN_REASON_##type: return #type
3665 
3666 const char *ieee80211_get_reason_code_string(u16 reason_code)
3667 {
3668     switch (reason_code) {
3669     case_WLAN(UNSPECIFIED);
3670     case_WLAN(PREV_AUTH_NOT_VALID);
3671     case_WLAN(DEAUTH_LEAVING);
3672     case_WLAN(DISASSOC_DUE_TO_INACTIVITY);
3673     case_WLAN(DISASSOC_AP_BUSY);
3674     case_WLAN(CLASS2_FRAME_FROM_NONAUTH_STA);
3675     case_WLAN(CLASS3_FRAME_FROM_NONASSOC_STA);
3676     case_WLAN(DISASSOC_STA_HAS_LEFT);
3677     case_WLAN(STA_REQ_ASSOC_WITHOUT_AUTH);
3678     case_WLAN(DISASSOC_BAD_POWER);
3679     case_WLAN(DISASSOC_BAD_SUPP_CHAN);
3680     case_WLAN(INVALID_IE);
3681     case_WLAN(MIC_FAILURE);
3682     case_WLAN(4WAY_HANDSHAKE_TIMEOUT);
3683     case_WLAN(GROUP_KEY_HANDSHAKE_TIMEOUT);
3684     case_WLAN(IE_DIFFERENT);
3685     case_WLAN(INVALID_GROUP_CIPHER);
3686     case_WLAN(INVALID_PAIRWISE_CIPHER);
3687     case_WLAN(INVALID_AKMP);
3688     case_WLAN(UNSUPP_RSN_VERSION);
3689     case_WLAN(INVALID_RSN_IE_CAP);
3690     case_WLAN(IEEE8021X_FAILED);
3691     case_WLAN(CIPHER_SUITE_REJECTED);
3692     case_WLAN(DISASSOC_UNSPECIFIED_QOS);
3693     case_WLAN(DISASSOC_QAP_NO_BANDWIDTH);
3694     case_WLAN(DISASSOC_LOW_ACK);
3695     case_WLAN(DISASSOC_QAP_EXCEED_TXOP);
3696     case_WLAN(QSTA_LEAVE_QBSS);
3697     case_WLAN(QSTA_NOT_USE);
3698     case_WLAN(QSTA_REQUIRE_SETUP);
3699     case_WLAN(QSTA_TIMEOUT);
3700     case_WLAN(QSTA_CIPHER_NOT_SUPP);
3701     case_WLAN(MESH_PEER_CANCELED);
3702     case_WLAN(MESH_MAX_PEERS);
3703     case_WLAN(MESH_CONFIG);
3704     case_WLAN(MESH_CLOSE);
3705     case_WLAN(MESH_MAX_RETRIES);
3706     case_WLAN(MESH_CONFIRM_TIMEOUT);
3707     case_WLAN(MESH_INVALID_GTK);
3708     case_WLAN(MESH_INCONSISTENT_PARAM);
3709     case_WLAN(MESH_INVALID_SECURITY);
3710     case_WLAN(MESH_PATH_ERROR);
3711     case_WLAN(MESH_PATH_NOFORWARD);
3712     case_WLAN(MESH_PATH_DEST_UNREACHABLE);
3713     case_WLAN(MAC_EXISTS_IN_MBSS);
3714     case_WLAN(MESH_CHAN_REGULATORY);
3715     case_WLAN(MESH_CHAN);
3716     default: return "<unknown>";
3717     }
3718 }
3719 
3720 static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
3721                      struct ieee80211_mgmt *mgmt, size_t len)
3722 {
3723     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3724     u16 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
3725 
3726     sdata_assert_lock(sdata);
3727 
3728     if (len < 24 + 2)
3729         return;
3730 
3731     if (!ether_addr_equal(mgmt->bssid, mgmt->sa)) {
3732         ieee80211_tdls_handle_disconnect(sdata, mgmt->sa, reason_code);
3733         return;
3734     }
3735 
3736     if (ifmgd->associated &&
3737         ether_addr_equal(mgmt->bssid, sdata->vif.cfg.ap_addr)) {
3738         sdata_info(sdata, "deauthenticated from %pM (Reason: %u=%s)\n",
3739                sdata->vif.cfg.ap_addr, reason_code,
3740                ieee80211_get_reason_code_string(reason_code));
3741 
3742         ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
3743 
3744         ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false,
3745                         reason_code, false);
3746         return;
3747     }
3748 
3749     if (ifmgd->assoc_data &&
3750         ether_addr_equal(mgmt->bssid, ifmgd->assoc_data->ap_addr)) {
3751         sdata_info(sdata,
3752                "deauthenticated from %pM while associating (Reason: %u=%s)\n",
3753                ifmgd->assoc_data->ap_addr, reason_code,
3754                ieee80211_get_reason_code_string(reason_code));
3755 
3756         ieee80211_destroy_assoc_data(sdata, ASSOC_ABANDON);
3757 
3758         cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
3759         return;
3760     }
3761 }
3762 
3763 
3764 static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
3765                        struct ieee80211_mgmt *mgmt, size_t len)
3766 {
3767     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3768     u16 reason_code;
3769 
3770     sdata_assert_lock(sdata);
3771 
3772     if (len < 24 + 2)
3773         return;
3774 
3775     if (!ifmgd->associated ||
3776         !ether_addr_equal(mgmt->bssid, sdata->vif.cfg.ap_addr))
3777         return;
3778 
3779     reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
3780 
3781     if (!ether_addr_equal(mgmt->bssid, mgmt->sa)) {
3782         ieee80211_tdls_handle_disconnect(sdata, mgmt->sa, reason_code);
3783         return;
3784     }
3785 
3786     sdata_info(sdata, "disassociated from %pM (Reason: %u=%s)\n",
3787            sdata->vif.cfg.ap_addr, reason_code,
3788            ieee80211_get_reason_code_string(reason_code));
3789 
3790     ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
3791 
3792     ieee80211_report_disconnect(sdata, (u8 *)mgmt, len, false, reason_code,
3793                     false);
3794 }
3795 
3796 static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
3797                 u8 *supp_rates, unsigned int supp_rates_len,
3798                 u32 *rates, u32 *basic_rates,
3799                 bool *have_higher_than_11mbit,
3800                 int *min_rate, int *min_rate_index,
3801                 int shift)
3802 {
3803     int i, j;
3804 
3805     for (i = 0; i < supp_rates_len; i++) {
3806         int rate = supp_rates[i] & 0x7f;
3807         bool is_basic = !!(supp_rates[i] & 0x80);
3808 
3809         if ((rate * 5 * (1 << shift)) > 110)
3810             *have_higher_than_11mbit = true;
3811 
3812         /*
3813          * Skip HT, VHT, HE and SAE H2E only BSS membership selectors
3814          * since they're not rates.
3815          *
3816          * Note: Even though the membership selector and the basic
3817          *   rate flag share the same bit, they are not exactly
3818          *   the same.
3819          */
3820         if (supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_HT_PHY) ||
3821             supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_VHT_PHY) ||
3822             supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_HE_PHY) ||
3823             supp_rates[i] == (0x80 | BSS_MEMBERSHIP_SELECTOR_SAE_H2E))
3824             continue;
3825 
3826         for (j = 0; j < sband->n_bitrates; j++) {
3827             struct ieee80211_rate *br;
3828             int brate;
3829 
3830             br = &sband->bitrates[j];
3831 
3832             brate = DIV_ROUND_UP(br->bitrate, (1 << shift) * 5);
3833             if (brate == rate) {
3834                 *rates |= BIT(j);
3835                 if (is_basic)
3836                     *basic_rates |= BIT(j);
3837                 if ((rate * 5) < *min_rate) {
3838                     *min_rate = rate * 5;
3839                     *min_rate_index = j;
3840                 }
3841                 break;
3842             }
3843         }
3844     }
3845 }
3846 
3847 static bool ieee80211_twt_req_supported(const struct link_sta_info *link_sta,
3848                     const struct ieee802_11_elems *elems)
3849 {
3850     if (elems->ext_capab_len < 10)
3851         return false;
3852 
3853     if (!(elems->ext_capab[9] & WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT))
3854         return false;
3855 
3856     return link_sta->pub->he_cap.he_cap_elem.mac_cap_info[0] &
3857         IEEE80211_HE_MAC_CAP0_TWT_RES;
3858 }
3859 
3860 static int ieee80211_recalc_twt_req(struct ieee80211_link_data *link,
3861                     struct link_sta_info *link_sta,
3862                     struct ieee802_11_elems *elems)
3863 {
3864     bool twt = ieee80211_twt_req_supported(link_sta, elems);
3865 
3866     if (link->conf->twt_requester != twt) {
3867         link->conf->twt_requester = twt;
3868         return BSS_CHANGED_TWT;
3869     }
3870     return 0;
3871 }
3872 
3873 static bool ieee80211_twt_bcast_support(struct ieee80211_sub_if_data *sdata,
3874                     struct ieee80211_bss_conf *bss_conf,
3875                     struct ieee80211_supported_band *sband,
3876                     struct link_sta_info *link_sta)
3877 {
3878     const struct ieee80211_sta_he_cap *own_he_cap =
3879         ieee80211_get_he_iftype_cap(sband,
3880                         ieee80211_vif_type_p2p(&sdata->vif));
3881 
3882     return bss_conf->he_support &&
3883         (link_sta->pub->he_cap.he_cap_elem.mac_cap_info[2] &
3884             IEEE80211_HE_MAC_CAP2_BCAST_TWT) &&
3885         own_he_cap &&
3886         (own_he_cap->he_cap_elem.mac_cap_info[2] &
3887             IEEE80211_HE_MAC_CAP2_BCAST_TWT);
3888 }
3889 
3890 static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
3891                     struct link_sta_info *link_sta,
3892                     struct cfg80211_bss *cbss,
3893                     struct ieee80211_mgmt *mgmt,
3894                     const u8 *elem_start,
3895                     unsigned int elem_len,
3896                     u64 *changed)
3897 {
3898     struct ieee80211_sub_if_data *sdata = link->sdata;
3899     struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
3900     struct ieee80211_bss_conf *bss_conf = link->conf;
3901     struct ieee80211_local *local = sdata->local;
3902     struct ieee80211_elems_parse_params parse_params = {
3903         .start = elem_start,
3904         .len = elem_len,
3905         .bss = cbss,
3906         .link_id = link == &sdata->deflink ? -1 : link->link_id,
3907     };
3908     bool is_6ghz = cbss->channel->band == NL80211_BAND_6GHZ;
3909     bool is_s1g = cbss->channel->band == NL80211_BAND_S1GHZ;
3910     const struct cfg80211_bss_ies *bss_ies = NULL;
3911     struct ieee80211_supported_band *sband;
3912     struct ieee802_11_elems *elems;
3913     u16 capab_info;
3914     bool ret;
3915 
3916     elems = ieee802_11_parse_elems_full(&parse_params);
3917     if (!elems)
3918         return false;
3919 
3920     /* FIXME: use from STA profile element after parsing that */
3921     capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
3922 
3923     if (!is_s1g && !elems->supp_rates) {
3924         sdata_info(sdata, "no SuppRates element in AssocResp\n");
3925         ret = false;
3926         goto out;
3927     }
3928 
3929     link->u.mgd.tdls_chan_switch_prohibited =
3930         elems->ext_capab && elems->ext_capab_len >= 5 &&
3931         (elems->ext_capab[4] & WLAN_EXT_CAPA5_TDLS_CH_SW_PROHIBITED);
3932 
3933     /*
3934      * Some APs are erroneously not including some information in their
3935      * (re)association response frames. Try to recover by using the data
3936      * from the beacon or probe response. This seems to afflict mobile
3937      * 2G/3G/4G wifi routers, reported models include the "Onda PN51T",
3938      * "Vodafone PocketWiFi 2", "ZTE MF60" and a similar T-Mobile device.
3939      */
3940     if (!is_6ghz &&
3941         ((assoc_data->wmm && !elems->wmm_param) ||
3942          (!(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HT) &&
3943           (!elems->ht_cap_elem || !elems->ht_operation)) ||
3944          (!(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT) &&
3945           (!elems->vht_cap_elem || !elems->vht_operation)))) {
3946         const struct cfg80211_bss_ies *ies;
3947         struct ieee802_11_elems *bss_elems;
3948 
3949         rcu_read_lock();
3950         ies = rcu_dereference(cbss->ies);
3951         if (ies)
3952             bss_ies = kmemdup(ies, sizeof(*ies) + ies->len,
3953                       GFP_ATOMIC);
3954         rcu_read_unlock();
3955         if (!bss_ies) {
3956             ret = false;
3957             goto out;
3958         }
3959 
3960         parse_params.start = bss_ies->data;
3961         parse_params.len = bss_ies->len;
3962         bss_elems = ieee802_11_parse_elems_full(&parse_params);
3963         if (!bss_elems) {
3964             ret = false;
3965             goto out;
3966         }
3967 
3968         if (assoc_data->wmm &&
3969             !elems->wmm_param && bss_elems->wmm_param) {
3970             elems->wmm_param = bss_elems->wmm_param;
3971             sdata_info(sdata,
3972                    "AP bug: WMM param missing from AssocResp\n");
3973         }
3974 
3975         /*
3976          * Also check if we requested HT/VHT, otherwise the AP doesn't
3977          * have to include the IEs in the (re)association response.
3978          */
3979         if (!elems->ht_cap_elem && bss_elems->ht_cap_elem &&
3980             !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HT)) {
3981             elems->ht_cap_elem = bss_elems->ht_cap_elem;
3982             sdata_info(sdata,
3983                    "AP bug: HT capability missing from AssocResp\n");
3984         }
3985         if (!elems->ht_operation && bss_elems->ht_operation &&
3986             !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HT)) {
3987             elems->ht_operation = bss_elems->ht_operation;
3988             sdata_info(sdata,
3989                    "AP bug: HT operation missing from AssocResp\n");
3990         }
3991         if (!elems->vht_cap_elem && bss_elems->vht_cap_elem &&
3992             !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT)) {
3993             elems->vht_cap_elem = bss_elems->vht_cap_elem;
3994             sdata_info(sdata,
3995                    "AP bug: VHT capa missing from AssocResp\n");
3996         }
3997         if (!elems->vht_operation && bss_elems->vht_operation &&
3998             !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT)) {
3999             elems->vht_operation = bss_elems->vht_operation;
4000             sdata_info(sdata,
4001                    "AP bug: VHT operation missing from AssocResp\n");
4002         }
4003 
4004         kfree(bss_elems);
4005     }
4006 
4007     /*
4008      * We previously checked these in the beacon/probe response, so
4009      * they should be present here. This is just a safety net.
4010      */
4011     if (!is_6ghz && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HT) &&
4012         (!elems->wmm_param || !elems->ht_cap_elem || !elems->ht_operation)) {
4013         sdata_info(sdata,
4014                "HT AP is missing WMM params or HT capability/operation\n");
4015         ret = false;
4016         goto out;
4017     }
4018 
4019     if (!is_6ghz && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT) &&
4020         (!elems->vht_cap_elem || !elems->vht_operation)) {
4021         sdata_info(sdata,
4022                "VHT AP is missing VHT capability/operation\n");
4023         ret = false;
4024         goto out;
4025     }
4026 
4027     if (is_6ghz && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HE) &&
4028         !elems->he_6ghz_capa) {
4029         sdata_info(sdata,
4030                "HE 6 GHz AP is missing HE 6 GHz band capability\n");
4031         ret = false;
4032         goto out;
4033     }
4034 
4035     sband = ieee80211_get_link_sband(link);
4036     if (!sband) {
4037         ret = false;
4038         goto out;
4039     }
4040 
4041     if (!(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HE) &&
4042         (!elems->he_cap || !elems->he_operation)) {
4043         sdata_info(sdata,
4044                "HE AP is missing HE capability/operation\n");
4045         ret = false;
4046         goto out;
4047     }
4048 
4049     /* Set up internal HT/VHT capabilities */
4050     if (elems->ht_cap_elem && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HT))
4051         ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
4052                           elems->ht_cap_elem,
4053                           link_sta);
4054 
4055     if (elems->vht_cap_elem && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT))
4056         ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
4057                             elems->vht_cap_elem,
4058                             link_sta);
4059 
4060     if (elems->he_operation && !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HE) &&
4061         elems->he_cap) {
4062         ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband,
4063                           elems->he_cap,
4064                           elems->he_cap_len,
4065                           elems->he_6ghz_capa,
4066                           link_sta);
4067 
4068         bss_conf->he_support = link_sta->pub->he_cap.has_he;
4069         if (elems->rsnx && elems->rsnx_len &&
4070             (elems->rsnx[0] & WLAN_RSNX_CAPA_PROTECTED_TWT) &&
4071             wiphy_ext_feature_isset(local->hw.wiphy,
4072                         NL80211_EXT_FEATURE_PROTECTED_TWT))
4073             bss_conf->twt_protected = true;
4074         else
4075             bss_conf->twt_protected = false;
4076 
4077         *changed |= ieee80211_recalc_twt_req(link, link_sta, elems);
4078 
4079         if (elems->eht_operation && elems->eht_cap &&
4080             !(link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_EHT)) {
4081             ieee80211_eht_cap_ie_to_sta_eht_cap(sdata, sband,
4082                                 elems->he_cap,
4083                                 elems->he_cap_len,
4084                                 elems->eht_cap,
4085                                 elems->eht_cap_len,
4086                                 link_sta);
4087 
4088             bss_conf->eht_support = link_sta->pub->eht_cap.has_eht;
4089         } else {
4090             bss_conf->eht_support = false;
4091         }
4092     } else {
4093         bss_conf->he_support = false;
4094         bss_conf->twt_requester = false;
4095         bss_conf->twt_protected = false;
4096         bss_conf->eht_support = false;
4097     }
4098 
4099     bss_conf->twt_broadcast =
4100         ieee80211_twt_bcast_support(sdata, bss_conf, sband, link_sta);
4101 
4102     if (bss_conf->he_support) {
4103         bss_conf->he_bss_color.color =
4104             le32_get_bits(elems->he_operation->he_oper_params,
4105                       IEEE80211_HE_OPERATION_BSS_COLOR_MASK);
4106         bss_conf->he_bss_color.partial =
4107             le32_get_bits(elems->he_operation->he_oper_params,
4108                       IEEE80211_HE_OPERATION_PARTIAL_BSS_COLOR);
4109         bss_conf->he_bss_color.enabled =
4110             !le32_get_bits(elems->he_operation->he_oper_params,
4111                        IEEE80211_HE_OPERATION_BSS_COLOR_DISABLED);
4112 
4113         if (bss_conf->he_bss_color.enabled)
4114             *changed |= BSS_CHANGED_HE_BSS_COLOR;
4115 
4116         bss_conf->htc_trig_based_pkt_ext =
4117             le32_get_bits(elems->he_operation->he_oper_params,
4118                       IEEE80211_HE_OPERATION_DFLT_PE_DURATION_MASK);
4119         bss_conf->frame_time_rts_th =
4120             le32_get_bits(elems->he_operation->he_oper_params,
4121                       IEEE80211_HE_OPERATION_RTS_THRESHOLD_MASK);
4122 
4123         bss_conf->uora_exists = !!elems->uora_element;
4124         if (elems->uora_element)
4125             bss_conf->uora_ocw_range = elems->uora_element[0];
4126 
4127         ieee80211_he_op_ie_to_bss_conf(&sdata->vif, elems->he_operation);
4128         ieee80211_he_spr_ie_to_bss_conf(&sdata->vif, elems->he_spr);
4129         /* TODO: OPEN: what happens if BSS color disable is set? */
4130     }
4131 
4132     if (cbss->transmitted_bss) {
4133         bss_conf->nontransmitted = true;
4134         ether_addr_copy(bss_conf->transmitter_bssid,
4135                 cbss->transmitted_bss->bssid);
4136         bss_conf->bssid_indicator = cbss->max_bssid_indicator;
4137         bss_conf->bssid_index = cbss->bssid_index;
4138     }
4139 
4140     /*
4141      * Some APs, e.g. Netgear WNDR3700, report invalid HT operation data
4142      * in their association response, so ignore that data for our own
4143      * configuration. If it changed since the last beacon, we'll get the
4144      * next beacon and update then.
4145      */
4146 
4147     /*
4148      * If an operating mode notification IE is present, override the
4149      * NSS calculation (that would be done in rate_control_rate_init())
4150      * and use the # of streams from that element.
4151      */
4152     if (elems->opmode_notif &&
4153         !(*elems->opmode_notif & IEEE80211_OPMODE_NOTIF_RX_NSS_TYPE_BF)) {
4154         u8 nss;
4155 
4156         nss = *elems->opmode_notif & IEEE80211_OPMODE_NOTIF_RX_NSS_MASK;
4157         nss >>= IEEE80211_OPMODE_NOTIF_RX_NSS_SHIFT;
4158         nss += 1;
4159         link_sta->pub->rx_nss = nss;
4160     }
4161 
4162     /*
4163      * Always handle WMM once after association regardless
4164      * of the first value the AP uses. Setting -1 here has
4165      * that effect because the AP values is an unsigned
4166      * 4-bit value.
4167      */
4168     link->u.mgd.wmm_last_param_set = -1;
4169     link->u.mgd.mu_edca_last_param_set = -1;
4170 
4171     if (link->u.mgd.disable_wmm_tracking) {
4172         ieee80211_set_wmm_default(link, false, false);
4173     } else if (!ieee80211_sta_wmm_params(local, link, elems->wmm_param,
4174                          elems->wmm_param_len,
4175                          elems->mu_edca_param_set)) {
4176         /* still enable QoS since we might have HT/VHT */
4177         ieee80211_set_wmm_default(link, false, true);
4178         /* disable WMM tracking in this case to disable
4179          * tracking WMM parameter changes in the beacon if
4180          * the parameters weren't actually valid. Doing so
4181          * avoids changing parameters very strangely when
4182          * the AP is going back and forth between valid and
4183          * invalid parameters.
4184          */
4185         link->u.mgd.disable_wmm_tracking = true;
4186     }
4187 
4188     if (elems->max_idle_period_ie) {
4189         bss_conf->max_idle_period =
4190             le16_to_cpu(elems->max_idle_period_ie->max_idle_period);
4191         bss_conf->protected_keep_alive =
4192             !!(elems->max_idle_period_ie->idle_options &
4193                WLAN_IDLE_OPTIONS_PROTECTED_KEEP_ALIVE);
4194         *changed |= BSS_CHANGED_KEEP_ALIVE;
4195     } else {
4196         bss_conf->max_idle_period = 0;
4197         bss_conf->protected_keep_alive = false;
4198     }
4199 
4200     /* set assoc capability (AID was already set earlier),
4201      * ieee80211_set_associated() will tell the driver */
4202     bss_conf->assoc_capability = capab_info;
4203 
4204     ret = true;
4205 out:
4206     kfree(elems);
4207     kfree(bss_ies);
4208     return ret;
4209 }
4210 
4211 static int ieee80211_mgd_setup_link_sta(struct ieee80211_link_data *link,
4212                     struct sta_info *sta,
4213                     struct link_sta_info *link_sta,
4214                     struct cfg80211_bss *cbss)
4215 {
4216     struct ieee80211_sub_if_data *sdata = link->sdata;
4217     struct ieee80211_local *local = sdata->local;
4218     struct ieee80211_bss *bss = (void *)cbss->priv;
4219     u32 rates = 0, basic_rates = 0;
4220     bool have_higher_than_11mbit = false;
4221     int min_rate = INT_MAX, min_rate_index = -1;
4222     /* this is clearly wrong for MLO but we'll just remove it later */
4223     int shift = ieee80211_vif_get_shift(&sdata->vif);
4224     struct ieee80211_supported_band *sband;
4225 
4226     memcpy(link_sta->addr, cbss->bssid, ETH_ALEN);
4227     memcpy(link_sta->pub->addr, cbss->bssid, ETH_ALEN);
4228 
4229     /* TODO: S1G Basic Rate Set is expressed elsewhere */
4230     if (cbss->channel->band == NL80211_BAND_S1GHZ) {
4231         ieee80211_s1g_sta_rate_init(sta);
4232         return 0;
4233     }
4234 
4235     sband = local->hw.wiphy->bands[cbss->channel->band];
4236 
4237     ieee80211_get_rates(sband, bss->supp_rates, bss->supp_rates_len,
4238                 &rates, &basic_rates, &have_higher_than_11mbit,
4239                 &min_rate, &min_rate_index, shift);
4240 
4241     /*
4242      * This used to be a workaround for basic rates missing
4243      * in the association response frame. Now that we no
4244      * longer use the basic rates from there, it probably
4245      * doesn't happen any more, but keep the workaround so
4246      * in case some *other* APs are buggy in different ways
4247      * we can connect -- with a warning.
4248      * Allow this workaround only in case the AP provided at least
4249      * one rate.
4250      */
4251     if (min_rate_index < 0) {
4252         link_info(link, "No legacy rates in association response\n");
4253         return -EINVAL;
4254     } else if (!basic_rates) {
4255         link_info(link, "No basic rates, using min rate instead\n");
4256         basic_rates = BIT(min_rate_index);
4257     }
4258 
4259     if (rates)
4260         link_sta->pub->supp_rates[cbss->channel->band] = rates;
4261     else
4262         link_info(link, "No rates found, keeping mandatory only\n");
4263 
4264     link->conf->basic_rates = basic_rates;
4265 
4266     /* cf. IEEE 802.11 9.2.12 */
4267     link->operating_11g_mode = sband->band == NL80211_BAND_2GHZ &&
4268                    have_higher_than_11mbit;
4269 
4270     return 0;
4271 }
4272 
4273 static u8 ieee80211_max_rx_chains(struct ieee80211_link_data *link,
4274                   struct cfg80211_bss *cbss)
4275 {
4276     struct ieee80211_he_mcs_nss_supp *he_mcs_nss_supp;
4277     const struct element *ht_cap_elem, *vht_cap_elem;
4278     const struct cfg80211_bss_ies *ies;
4279     const struct ieee80211_ht_cap *ht_cap;
4280     const struct ieee80211_vht_cap *vht_cap;
4281     const struct ieee80211_he_cap_elem *he_cap;
4282     const struct element *he_cap_elem;
4283     u16 mcs_80_map, mcs_160_map;
4284     int i, mcs_nss_size;
4285     bool support_160;
4286     u8 chains = 1;
4287 
4288     if (link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HT)
4289         return chains;
4290 
4291     ht_cap_elem = ieee80211_bss_get_elem(cbss, WLAN_EID_HT_CAPABILITY);
4292     if (ht_cap_elem && ht_cap_elem->datalen >= sizeof(*ht_cap)) {
4293         ht_cap = (void *)ht_cap_elem->data;
4294         chains = ieee80211_mcs_to_chains(&ht_cap->mcs);
4295         /*
4296          * TODO: use "Tx Maximum Number Spatial Streams Supported" and
4297          *   "Tx Unequal Modulation Supported" fields.
4298          */
4299     }
4300 
4301     if (link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_VHT)
4302         return chains;
4303 
4304     vht_cap_elem = ieee80211_bss_get_elem(cbss, WLAN_EID_VHT_CAPABILITY);
4305     if (vht_cap_elem && vht_cap_elem->datalen >= sizeof(*vht_cap)) {
4306         u8 nss;
4307         u16 tx_mcs_map;
4308 
4309         vht_cap = (void *)vht_cap_elem->data;
4310         tx_mcs_map = le16_to_cpu(vht_cap->supp_mcs.tx_mcs_map);
4311         for (nss = 8; nss > 0; nss--) {
4312             if (((tx_mcs_map >> (2 * (nss - 1))) & 3) !=
4313                     IEEE80211_VHT_MCS_NOT_SUPPORTED)
4314                 break;
4315         }
4316         /* TODO: use "Tx Highest Supported Long GI Data Rate" field? */
4317         chains = max(chains, nss);
4318     }
4319 
4320     if (link->u.mgd.conn_flags & IEEE80211_CONN_DISABLE_HE)
4321         return chains;
4322 
4323     ies = rcu_dereference(cbss->ies);
4324     he_cap_elem = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_CAPABILITY,
4325                          ies->data, ies->len);
4326 
4327     if (!he_cap_elem || he_cap_elem->datalen < sizeof(*he_cap))
4328         return chains;
4329 
4330     /* skip one byte ext_tag_id */
4331     he_cap = (void *)(he_cap_elem->data + 1);
4332     mcs_nss_size = ieee80211_he_mcs_nss_size(he_cap);
4333 
4334     /* invalid HE IE */
4335     if (he_cap_elem->datalen < 1 + mcs_nss_size + sizeof(*he_cap))
4336         return chains;
4337 
4338     /* mcs_nss is right after he_cap info */
4339     he_mcs_nss_supp = (void *)(he_cap + 1);
4340 
4341     mcs_80_map = le16_to_cpu(he_mcs_nss_supp->tx_mcs_80);
4342 
4343     for (i = 7; i >= 0; i--) {
4344         u8 mcs_80 = mcs_80_map >> (2 * i) & 3;
4345 
4346         if (mcs_80 != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
4347             chains = max_t(u8, chains, i + 1);
4348             break;
4349         }
4350     }
4351 
4352     support_160 = he_cap->phy_cap_info[0] &
4353               IEEE80211_HE_PHY_CAP0_CHANNEL_WIDTH_SET_160MHZ_IN_5G;
4354 
4355     if (!support_160)
4356         return chains;
4357 
4358     mcs_160_map = le16_to_cpu(he_mcs_nss_supp->tx_mcs_160);
4359     for (i = 7; i >= 0; i--) {
4360         u8 mcs_160 = mcs_160_map >> (2 * i) & 3;
4361 
4362         if (mcs_160 != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
4363             chains = max_t(u8, chains, i + 1);
4364             break;
4365         }
4366     }
4367 
4368     return chains;
4369 }
4370 
4371 static bool
4372 ieee80211_verify_peer_he_mcs_support(struct ieee80211_sub_if_data *sdata,
4373                      const struct cfg80211_bss_ies *ies,
4374                      const struct ieee80211_he_operation *he_op)
4375 {
4376     const struct element *he_cap_elem;
4377     const struct ieee80211_he_cap_elem *he_cap;
4378     struct ieee80211_he_mcs_nss_supp *he_mcs_nss_supp;
4379     u16 mcs_80_map_tx, mcs_80_map_rx;
4380     u16 ap_min_req_set;
4381     int mcs_nss_size;
4382     int nss;
4383 
4384     he_cap_elem = cfg80211_find_ext_elem(WLAN_EID_EXT_HE_CAPABILITY,
4385                          ies->data, ies->len);
4386 
4387     /* invalid HE IE */
4388     if (!he_cap_elem || he_cap_elem->datalen < 1 + sizeof(*he_cap)) {
4389         sdata_info(sdata,
4390                "Invalid HE elem, Disable HE\n");
4391         return false;
4392     }
4393 
4394     /* skip one byte ext_tag_id */
4395     he_cap = (void *)(he_cap_elem->data + 1);
4396     mcs_nss_size = ieee80211_he_mcs_nss_size(he_cap);
4397 
4398     /* invalid HE IE */
4399     if (he_cap_elem->datalen < 1 + sizeof(*he_cap) + mcs_nss_size) {
4400         sdata_info(sdata,
4401                "Invalid HE elem with nss size, Disable HE\n");
4402         return false;
4403     }
4404 
4405     /* mcs_nss is right after he_cap info */
4406     he_mcs_nss_supp = (void *)(he_cap + 1);
4407 
4408     mcs_80_map_tx = le16_to_cpu(he_mcs_nss_supp->tx_mcs_80);
4409     mcs_80_map_rx = le16_to_cpu(he_mcs_nss_supp->rx_mcs_80);
4410 
4411     /* P802.11-REVme/D0.3
4412      * 27.1.1 Introduction to the HE PHY
4413      * ...
4414      * An HE STA shall support the following features:
4415      * ...
4416      * Single spatial stream HE-MCSs 0 to 7 (transmit and receive) in all
4417      * supported channel widths for HE SU PPDUs
4418      */
4419     if ((mcs_80_map_tx & 0x3) == IEEE80211_HE_MCS_NOT_SUPPORTED ||
4420         (mcs_80_map_rx & 0x3) == IEEE80211_HE_MCS_NOT_SUPPORTED) {
4421         sdata_info(sdata,
4422                "Missing mandatory rates for 1 Nss, rx 0x%x, tx 0x%x, disable HE\n",
4423                mcs_80_map_tx, mcs_80_map_rx);
4424         return false;
4425     }
4426 
4427     if (!he_op)
4428         return true;
4429 
4430     ap_min_req_set = le16_to_cpu(he_op->he_mcs_nss_set);
4431 
4432     /*
4433      * Apparently iPhone 13 (at least iOS version 15.3.1) sets this to all
4434      * zeroes, which is nonsense, and completely inconsistent with itself
4435      * (it doesn't have 8 streams). Accept the settings in this case anyway.
4436      */
4437     if (!ap_min_req_set)
4438         return true;
4439 
4440     /* make sure the AP is consistent with itself
4441      *
4442      * P802.11-REVme/D0.3
4443      * 26.17.1 Basic HE BSS operation
4444      *
4445      * A STA that is operating in an HE BSS shall be able to receive and
4446      * transmit at each of the <HE-MCS, NSS> tuple values indicated by the
4447      * Basic HE-MCS And NSS Set field of the HE Operation parameter of the
4448      * MLME-START.request primitive and shall be able to receive at each of
4449      * the <HE-MCS, NSS> tuple values indicated by the Supported HE-MCS and
4450      * NSS Set field in the HE Capabilities parameter of the MLMESTART.request
4451      * primitive
4452      */
4453     for (nss = 8; nss > 0; nss--) {
4454         u8 ap_op_val = (ap_min_req_set >> (2 * (nss - 1))) & 3;
4455         u8 ap_rx_val;
4456         u8 ap_tx_val;
4457 
4458         if (ap_op_val == IEEE80211_HE_MCS_NOT_SUPPORTED)
4459             continue;
4460 
4461         ap_rx_val = (mcs_80_map_rx >> (2 * (nss - 1))) & 3;
4462         ap_tx_val = (mcs_80_map_tx >> (2 * (nss - 1))) & 3;
4463 
4464         if (ap_rx_val == IEEE80211_HE_MCS_NOT_SUPPORTED ||
4465             ap_tx_val == IEEE80211_HE_MCS_NOT_SUPPORTED ||
4466             ap_rx_val < ap_op_val || ap_tx_val < ap_op_val) {
4467             sdata_info(sdata,
4468                    "Invalid rates for %d Nss, rx %d, tx %d oper %d, disable HE\n",
4469                    nss, ap_rx_val, ap_rx_val, ap_op_val);
4470             return false;
4471         }
4472     }
4473 
4474     return true;
4475 }
4476 
4477 static bool
4478 ieee80211_verify_sta_he_mcs_support(struct ieee80211_sub_if_data *sdata,
4479                     struct ieee80211_supported_band *sband,
4480                     const struct ieee80211_he_operation *he_op)
4481 {
4482     const struct ieee80211_sta_he_cap *sta_he_cap =
4483         ieee80211_get_he_iftype_cap(sband,
4484                         ieee80211_vif_type_p2p(&sdata->vif));
4485     u16 ap_min_req_set;
4486     int i;
4487 
4488     if (!sta_he_cap || !he_op)
4489         return false;
4490 
4491     ap_min_req_set = le16_to_cpu(he_op->he_mcs_nss_set);
4492 
4493     /*
4494      * Apparently iPhone 13 (at least iOS version 15.3.1) sets this to all
4495      * zeroes, which is nonsense, and completely inconsistent with itself
4496      * (it doesn't have 8 streams). Accept the settings in this case anyway.
4497      */
4498     if (!ap_min_req_set)
4499         return true;
4500 
4501     /* Need to go over for 80MHz, 160MHz and for 80+80 */
4502     for (i = 0; i < 3; i++) {
4503         const struct ieee80211_he_mcs_nss_supp *sta_mcs_nss_supp =
4504             &sta_he_cap->he_mcs_nss_supp;
4505         u16 sta_mcs_map_rx =
4506             le16_to_cpu(((__le16 *)sta_mcs_nss_supp)[2 * i]);
4507         u16 sta_mcs_map_tx =
4508             le16_to_cpu(((__le16 *)sta_mcs_nss_supp)[2 * i + 1]);
4509         u8 nss;
4510         bool verified = true;
4511 
4512         /*
4513          * For each band there is a maximum of 8 spatial streams
4514          * possible. Each of the sta_mcs_map_* is a 16-bit struct built
4515          * of 2 bits per NSS (1-8), with the values defined in enum
4516          * ieee80211_he_mcs_support. Need to make sure STA TX and RX
4517          * capabilities aren't less than the AP's minimum requirements
4518          * for this HE BSS per SS.
4519          * It is enough to find one such band that meets the reqs.
4520          */
4521         for (nss = 8; nss > 0; nss--) {
4522             u8 sta_rx_val = (sta_mcs_map_rx >> (2 * (nss - 1))) & 3;
4523             u8 sta_tx_val = (sta_mcs_map_tx >> (2 * (nss - 1))) & 3;
4524             u8 ap_val = (ap_min_req_set >> (2 * (nss - 1))) & 3;
4525 
4526             if (ap_val == IEEE80211_HE_MCS_NOT_SUPPORTED)
4527                 continue;
4528 
4529             /*
4530              * Make sure the HE AP doesn't require MCSs that aren't
4531              * supported by the client as required by spec
4532              *
4533              * P802.11-REVme/D0.3
4534              * 26.17.1 Basic HE BSS operation
4535              *
4536              * An HE STA shall not attempt to join * (MLME-JOIN.request primitive)
4537              * a BSS, unless it supports (i.e., is able to both transmit and
4538              * receive using) all of the <HE-MCS, NSS> tuples in the basic
4539              * HE-MCS and NSS set.
4540              */
4541             if (sta_rx_val == IEEE80211_HE_MCS_NOT_SUPPORTED ||
4542                 sta_tx_val == IEEE80211_HE_MCS_NOT_SUPPORTED ||
4543                 (ap_val > sta_rx_val) || (ap_val > sta_tx_val)) {
4544                 verified = false;
4545                 break;
4546             }
4547         }
4548 
4549         if (verified)
4550             return true;
4551     }
4552 
4553     /* If here, STA doesn't meet AP's HE min requirements */
4554     return false;
4555 }
4556 
4557 static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
4558                   struct ieee80211_link_data *link,
4559                   struct cfg80211_bss *cbss,
4560                   ieee80211_conn_flags_t *conn_flags)
4561 {
4562     struct ieee80211_local *local = sdata->local;
4563     const struct ieee80211_ht_cap *ht_cap = NULL;
4564     const struct ieee80211_ht_operation *ht_oper = NULL;
4565     const struct ieee80211_vht_operation *vht_oper = NULL;
4566     const struct ieee80211_he_operation *he_oper = NULL;
4567     const struct ieee80211_eht_operation *eht_oper = NULL;
4568     const struct ieee80211_s1g_oper_ie *s1g_oper = NULL;
4569     struct ieee80211_supported_band *sband;
4570     struct cfg80211_chan_def chandef;
4571     bool is_6ghz = cbss->channel->band == NL80211_BAND_6GHZ;
4572     bool is_5ghz = cbss->channel->band == NL80211_BAND_5GHZ;
4573     struct ieee80211_bss *bss = (void *)cbss->priv;
4574     struct ieee802_11_elems *elems;
4575     const struct cfg80211_bss_ies *ies;
4576     int ret;
4577     u32 i;
4578     bool have_80mhz;
4579 
4580     rcu_read_lock();
4581 
4582     ies = rcu_dereference(cbss->ies);
4583     elems = ieee802_11_parse_elems(ies->data, ies->len, false, cbss);
4584     if (!elems) {
4585         rcu_read_unlock();
4586         return -ENOMEM;
4587     }
4588 
4589     sband = local->hw.wiphy->bands[cbss->channel->band];
4590 
4591     *conn_flags &= ~(IEEE80211_CONN_DISABLE_40MHZ |
4592              IEEE80211_CONN_DISABLE_80P80MHZ |
4593              IEEE80211_CONN_DISABLE_160MHZ);
4594 
4595     /* disable HT/VHT/HE if we don't support them */
4596     if (!sband->ht_cap.ht_supported && !is_6ghz) {
4597         mlme_dbg(sdata, "HT not supported, disabling HT/VHT/HE/EHT\n");
4598         *conn_flags |= IEEE80211_CONN_DISABLE_HT;
4599         *conn_flags |= IEEE80211_CONN_DISABLE_VHT;
4600         *conn_flags |= IEEE80211_CONN_DISABLE_HE;
4601         *conn_flags |= IEEE80211_CONN_DISABLE_EHT;
4602     }
4603 
4604     if (!sband->vht_cap.vht_supported && is_5ghz) {
4605         mlme_dbg(sdata, "VHT not supported, disabling VHT/HE/EHT\n");
4606         *conn_flags |= IEEE80211_CONN_DISABLE_VHT;
4607         *conn_flags |= IEEE80211_CONN_DISABLE_HE;
4608         *conn_flags |= IEEE80211_CONN_DISABLE_EHT;
4609     }
4610 
4611     if (!ieee80211_get_he_iftype_cap(sband,
4612                      ieee80211_vif_type_p2p(&sdata->vif))) {
4613         mlme_dbg(sdata, "HE not supported, disabling HE and EHT\n");
4614         *conn_flags |= IEEE80211_CONN_DISABLE_HE;
4615         *conn_flags |= IEEE80211_CONN_DISABLE_EHT;
4616     }
4617 
4618     if (!ieee80211_get_eht_iftype_cap(sband,
4619                       ieee80211_vif_type_p2p(&sdata->vif))) {
4620         mlme_dbg(sdata, "EHT not supported, disabling EHT\n");
4621         *conn_flags |= IEEE80211_CONN_DISABLE_EHT;
4622     }
4623 
4624     if (!(*conn_flags & IEEE80211_CONN_DISABLE_HT) && !is_6ghz) {
4625         ht_oper = elems->ht_operation;
4626         ht_cap = elems->ht_cap_elem;
4627 
4628         if (!ht_cap) {
4629             *conn_flags |= IEEE80211_CONN_DISABLE_HT;
4630             ht_oper = NULL;
4631         }
4632     }
4633 
4634     if (!(*conn_flags & IEEE80211_CONN_DISABLE_VHT) && !is_6ghz) {
4635         vht_oper = elems->vht_operation;
4636         if (vht_oper && !ht_oper) {
4637             vht_oper = NULL;
4638             sdata_info(sdata,
4639                    "AP advertised VHT without HT, disabling HT/VHT/HE\n");
4640             *conn_flags |= IEEE80211_CONN_DISABLE_HT;
4641             *conn_flags |= IEEE80211_CONN_DISABLE_VHT;
4642             *conn_flags |= IEEE80211_CONN_DISABLE_HE;
4643             *conn_flags |= IEEE80211_CONN_DISABLE_EHT;
4644         }
4645 
4646         if (!elems->vht_cap_elem) {
4647             sdata_info(sdata,
4648                    "bad VHT capabilities, disabling VHT\n");
4649             *conn_flags |= IEEE80211_CONN_DISABLE_VHT;
4650             vht_oper = NULL;
4651         }
4652     }
4653 
4654     if (!(*conn_flags & IEEE80211_CONN_DISABLE_HE)) {
4655         he_oper = elems->he_operation;
4656 
4657         if (link && is_6ghz) {
4658             struct ieee80211_bss_conf *bss_conf;
4659             u8 j = 0;
4660 
4661             bss_conf = link->conf;
4662 
4663             if (elems->pwr_constr_elem)
4664                 bss_conf->pwr_reduction = *elems->pwr_constr_elem;
4665 
4666             BUILD_BUG_ON(ARRAY_SIZE(bss_conf->tx_pwr_env) !=
4667                      ARRAY_SIZE(elems->tx_pwr_env));
4668 
4669             for (i = 0; i < elems->tx_pwr_env_num; i++) {
4670                 if (elems->tx_pwr_env_len[i] >
4671                     sizeof(bss_conf->tx_pwr_env[j]))
4672                     continue;
4673 
4674                 bss_conf->tx_pwr_env_num++;
4675                 memcpy(&bss_conf->tx_pwr_env[j], elems->tx_pwr_env[i],
4676                        elems->tx_pwr_env_len[i]);
4677                 j++;
4678             }
4679         }
4680 
4681         if (!ieee80211_verify_peer_he_mcs_support(sdata, ies, he_oper) ||
4682             !ieee80211_verify_sta_he_mcs_support(sdata, sband, he_oper))
4683             *conn_flags |= IEEE80211_CONN_DISABLE_HE |
4684                        IEEE80211_CONN_DISABLE_EHT;
4685     }
4686 
4687     /*
4688      * EHT requires HE to be supported as well. Specifically for 6 GHz
4689      * channels, the operation channel information can only be deduced from
4690      * both the 6 GHz operation information (from the HE operation IE) and
4691      * EHT operation.
4692      */
4693     if (!(*conn_flags &
4694             (IEEE80211_CONN_DISABLE_HE |
4695              IEEE80211_CONN_DISABLE_EHT)) &&
4696         he_oper) {
4697         const struct cfg80211_bss_ies *cbss_ies;
4698         const u8 *eht_oper_ie;
4699 
4700         cbss_ies = rcu_dereference(cbss->ies);
4701         eht_oper_ie = cfg80211_find_ext_ie(WLAN_EID_EXT_EHT_OPERATION,
4702                            cbss_ies->data, cbss_ies->len);
4703         if (eht_oper_ie && eht_oper_ie[1] >=
4704             1 + sizeof(struct ieee80211_eht_operation))
4705             eht_oper = (void *)(eht_oper_ie + 3);
4706         else
4707             eht_oper = NULL;
4708     }
4709 
4710     /* Allow VHT if at least one channel on the sband supports 80 MHz */
4711     have_80mhz = false;
4712     for (i = 0; i < sband->n_channels; i++) {
4713         if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
4714                         IEEE80211_CHAN_NO_80MHZ))
4715             continue;
4716 
4717         have_80mhz = true;
4718         break;
4719     }
4720 
4721     if (!have_80mhz) {
4722         sdata_info(sdata, "80 MHz not supported, disabling VHT\n");
4723         *conn_flags |= IEEE80211_CONN_DISABLE_VHT;
4724     }
4725 
4726     if (sband->band == NL80211_BAND_S1GHZ) {
4727         s1g_oper = elems->s1g_oper;
4728         if (!s1g_oper)
4729             sdata_info(sdata,
4730                    "AP missing S1G operation element?\n");
4731     }
4732 
4733     *conn_flags |=
4734         ieee80211_determine_chantype(sdata, link, *conn_flags,
4735                          sband,
4736                          cbss->channel,
4737                          bss->vht_cap_info,
4738                          ht_oper, vht_oper,
4739                          he_oper, eht_oper,
4740                          s1g_oper,
4741                          &chandef, false);
4742 
4743     if (link)
4744         link->needed_rx_chains =
4745             min(ieee80211_max_rx_chains(link, cbss),
4746                 local->rx_chains);
4747 
4748     rcu_read_unlock();
4749     /* the element data was RCU protected so no longer valid anyway */
4750     kfree(elems);
4751     elems = NULL;
4752 
4753     if (*conn_flags & IEEE80211_CONN_DISABLE_HE && is_6ghz) {
4754         sdata_info(sdata, "Rejecting non-HE 6/7 GHz connection");
4755         return -EINVAL;
4756     }
4757 
4758     if (!link)
4759         return 0;
4760 
4761     /* will change later if needed */
4762     link->smps_mode = IEEE80211_SMPS_OFF;
4763 
4764     mutex_lock(&local->mtx);
4765     /*
4766      * If this fails (possibly due to channel context sharing
4767      * on incompatible channels, e.g. 80+80 and 160 sharing the
4768      * same control channel) try to use a smaller bandwidth.
4769      */
4770     ret = ieee80211_link_use_channel(link, &chandef,
4771                      IEEE80211_CHANCTX_SHARED);
4772 
4773     /* don't downgrade for 5 and 10 MHz channels, though. */
4774     if (chandef.width == NL80211_CHAN_WIDTH_5 ||
4775         chandef.width == NL80211_CHAN_WIDTH_10)
4776         goto out;
4777 
4778     while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) {
4779         *conn_flags |=
4780             ieee80211_chandef_downgrade(&chandef);
4781         ret = ieee80211_link_use_channel(link, &chandef,
4782                          IEEE80211_CHANCTX_SHARED);
4783     }
4784  out:
4785     mutex_unlock(&local->mtx);
4786     return ret;
4787 }
4788 
4789 static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
4790                     struct ieee80211_mgmt *mgmt,
4791                     struct ieee802_11_elems *elems,
4792                     const u8 *elem_start, unsigned int elem_len)
4793 {
4794     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
4795     struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
4796     struct ieee80211_local *local = sdata->local;
4797     unsigned int link_id;
4798     struct sta_info *sta;
4799     u64 changed[IEEE80211_MLD_MAX_NUM_LINKS] = {};
4800     int err;
4801 
4802     mutex_lock(&sdata->local->sta_mtx);
4803     /*
4804      * station info was already allocated and inserted before
4805      * the association and should be available to us
4806      */
4807     sta = sta_info_get(sdata, assoc_data->ap_addr);
4808     if (WARN_ON(!sta))
4809         goto out_err;
4810 
4811     if (sdata->vif.valid_links) {
4812         u16 valid_links = 0;
4813 
4814         for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
4815             if (!assoc_data->link[link_id].bss)
4816                 continue;
4817             valid_links |= BIT(link_id);
4818 
4819             if (link_id != assoc_data->assoc_link_id) {
4820                 err = ieee80211_sta_allocate_link(sta, link_id);
4821                 if (err)
4822                     goto out_err;
4823             }
4824         }
4825 
4826         ieee80211_vif_set_links(sdata, valid_links);
4827     }
4828 
4829     for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
4830         struct ieee80211_link_data *link;
4831         struct link_sta_info *link_sta;
4832 
4833         if (!assoc_data->link[link_id].bss)
4834             continue;
4835 
4836         link = sdata_dereference(sdata->link[link_id], sdata);
4837         if (WARN_ON(!link))
4838             goto out_err;
4839 
4840         if (sdata->vif.valid_links)
4841             link_info(link,
4842                   "local address %pM, AP link address %pM\n",
4843                   link->conf->addr,
4844                   assoc_data->link[link_id].bss->bssid);
4845 
4846         link_sta = rcu_dereference_protected(sta->link[link_id],
4847                              lockdep_is_held(&local->sta_mtx));
4848         if (WARN_ON(!link_sta))
4849             goto out_err;
4850 
4851         if (link_id != assoc_data->assoc_link_id) {
4852             err = ieee80211_prep_channel(sdata, link,
4853                              assoc_data->link[link_id].bss,
4854                              &link->u.mgd.conn_flags);
4855             if (err)
4856                 goto out_err;
4857         }
4858 
4859         err = ieee80211_mgd_setup_link_sta(link, sta, link_sta,
4860                            assoc_data->link[link_id].bss);
4861         if (err)
4862             goto out_err;
4863 
4864         if (!ieee80211_assoc_config_link(link, link_sta,
4865                          assoc_data->link[link_id].bss,
4866                          mgmt, elem_start, elem_len,
4867                          &changed[link_id]))
4868             goto out_err;
4869 
4870         if (link_id != assoc_data->assoc_link_id) {
4871             err = ieee80211_sta_activate_link(sta, link_id);
4872             if (err)
4873                 goto out_err;
4874         }
4875     }
4876 
4877     rate_control_rate_init(sta);
4878 
4879     if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) {
4880         set_sta_flag(sta, WLAN_STA_MFP);
4881         sta->sta.mfp = true;
4882     } else {
4883         sta->sta.mfp = false;
4884     }
4885 
4886     ieee80211_sta_set_max_amsdu_subframes(sta, elems->ext_capab,
4887                           elems->ext_capab_len);
4888 
4889     sta->sta.wme = (elems->wmm_param || elems->s1g_capab) &&
4890                local->hw.queues >= IEEE80211_NUM_ACS;
4891 
4892     err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
4893     if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
4894         err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
4895     if (err) {
4896         sdata_info(sdata,
4897                "failed to move station %pM to desired state\n",
4898                sta->sta.addr);
4899         WARN_ON(__sta_info_destroy(sta));
4900         goto out_err;
4901     }
4902 
4903     if (sdata->wdev.use_4addr)
4904         drv_sta_set_4addr(local, sdata, &sta->sta, true);
4905 
4906     mutex_unlock(&sdata->local->sta_mtx);
4907 
4908     ieee80211_set_associated(sdata, assoc_data, changed);
4909 
4910     /*
4911      * If we're using 4-addr mode, let the AP know that we're
4912      * doing so, so that it can create the STA VLAN on its side
4913      */
4914     if (ifmgd->use_4addr)
4915         ieee80211_send_4addr_nullfunc(local, sdata);
4916 
4917     /*
4918      * Start timer to probe the connection to the AP now.
4919      * Also start the timer that will detect beacon loss.
4920      */
4921     ieee80211_sta_reset_beacon_monitor(sdata);
4922     ieee80211_sta_reset_conn_monitor(sdata);
4923 
4924     return true;
4925 out_err:
4926     eth_zero_addr(sdata->vif.cfg.ap_addr);
4927     mutex_unlock(&sdata->local->sta_mtx);
4928     return false;
4929 }
4930 
4931 static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
4932                      struct ieee80211_mgmt *mgmt,
4933                      size_t len)
4934 {
4935     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
4936     struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
4937     u16 capab_info, status_code, aid;
4938     struct ieee802_11_elems *elems;
4939     int ac;
4940     const u8 *elem_start;
4941     unsigned int elem_len;
4942     bool reassoc;
4943     struct ieee80211_event event = {
4944         .type = MLME_EVENT,
4945         .u.mlme.data = ASSOC_EVENT,
4946     };
4947     struct ieee80211_prep_tx_info info = {};
4948     struct cfg80211_rx_assoc_resp resp = {
4949         .uapsd_queues = -1,
4950     };
4951     unsigned int link_id;
4952 
4953     sdata_assert_lock(sdata);
4954 
4955     if (!assoc_data)
4956         return;
4957 
4958     if (!ether_addr_equal(assoc_data->ap_addr, mgmt->bssid) ||
4959         !ether_addr_equal(assoc_data->ap_addr, mgmt->sa))
4960         return;
4961 
4962     /*
4963      * AssocResp and ReassocResp have identical structure, so process both
4964      * of them in this function.
4965      */
4966 
4967     if (len < 24 + 6)
4968         return;
4969 
4970     reassoc = ieee80211_is_reassoc_resp(mgmt->frame_control);
4971     capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
4972     status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code);
4973     if (assoc_data->s1g)
4974         elem_start = mgmt->u.s1g_assoc_resp.variable;
4975     else
4976         elem_start = mgmt->u.assoc_resp.variable;
4977 
4978     /*
4979      * Note: this may not be perfect, AP might misbehave - if
4980      * anyone needs to rely on perfect complete notification
4981      * with the exact right subtype, then we need to track what
4982      * we actually transmitted.
4983      */
4984     info.subtype = reassoc ? IEEE80211_STYPE_REASSOC_REQ :
4985                  IEEE80211_STYPE_ASSOC_REQ;
4986 
4987     if (assoc_data->fils_kek_len &&
4988         fils_decrypt_assoc_resp(sdata, (u8 *)mgmt, &len, assoc_data) < 0)
4989         return;
4990 
4991     elem_len = len - (elem_start - (u8 *)mgmt);
4992     elems = ieee802_11_parse_elems(elem_start, elem_len, false, NULL);
4993     if (!elems)
4994         goto notify_driver;
4995 
4996     if (elems->aid_resp)
4997         aid = le16_to_cpu(elems->aid_resp->aid);
4998     else if (assoc_data->s1g)
4999         aid = 0; /* TODO */
5000     else
5001         aid = le16_to_cpu(mgmt->u.assoc_resp.aid);
5002 
5003     /*
5004      * The 5 MSB of the AID field are reserved
5005      * (802.11-2016 9.4.1.8 AID field)
5006      */
5007     aid &= 0x7ff;
5008 
5009     sdata_info(sdata,
5010            "RX %sssocResp from %pM (capab=0x%x status=%d aid=%d)\n",
5011            reassoc ? "Rea" : "A", assoc_data->ap_addr,
5012            capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
5013 
5014     ifmgd->broken_ap = false;
5015 
5016     if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
5017         elems->timeout_int &&
5018         elems->timeout_int->type == WLAN_TIMEOUT_ASSOC_COMEBACK) {
5019         u32 tu, ms;
5020 
5021         cfg80211_assoc_comeback(sdata->dev, assoc_data->ap_addr,
5022                     le32_to_cpu(elems->timeout_int->value));
5023 
5024         tu = le32_to_cpu(elems->timeout_int->value);
5025         ms = tu * 1024 / 1000;
5026         sdata_info(sdata,
5027                "%pM rejected association temporarily; comeback duration %u TU (%u ms)\n",
5028                assoc_data->ap_addr, tu, ms);
5029         assoc_data->timeout = jiffies + msecs_to_jiffies(ms);
5030         assoc_data->timeout_started = true;
5031         if (ms > IEEE80211_ASSOC_TIMEOUT)
5032             run_again(sdata, assoc_data->timeout);
5033         goto notify_driver;
5034     }
5035 
5036     if (status_code != WLAN_STATUS_SUCCESS) {
5037         sdata_info(sdata, "%pM denied association (code=%d)\n",
5038                assoc_data->ap_addr, status_code);
5039         event.u.mlme.status = MLME_DENIED;
5040         event.u.mlme.reason = status_code;
5041         drv_event_callback(sdata->local, sdata, &event);
5042     } else {
5043         if (aid == 0 || aid > IEEE80211_MAX_AID) {
5044             sdata_info(sdata,
5045                    "invalid AID value %d (out of range), turn off PS\n",
5046                    aid);
5047             aid = 0;
5048             ifmgd->broken_ap = true;
5049         }
5050 
5051         if (sdata->vif.valid_links) {
5052             if (!elems->multi_link) {
5053                 sdata_info(sdata,
5054                        "MLO association with %pM but no multi-link element in response!\n",
5055                        assoc_data->ap_addr);
5056                 goto abandon_assoc;
5057             }
5058 
5059             if (le16_get_bits(elems->multi_link->control,
5060                       IEEE80211_ML_CONTROL_TYPE) !=
5061                     IEEE80211_ML_CONTROL_TYPE_BASIC) {
5062                 sdata_info(sdata,
5063                        "bad multi-link element (control=0x%x)\n",
5064                        le16_to_cpu(elems->multi_link->control));
5065                 goto abandon_assoc;
5066             } else {
5067                 struct ieee80211_mle_basic_common_info *common;
5068 
5069                 common = (void *)elems->multi_link->variable;
5070 
5071                 if (memcmp(assoc_data->ap_addr,
5072                        common->mld_mac_addr, ETH_ALEN)) {
5073                     sdata_info(sdata,
5074                            "AP MLD MAC address mismatch: got %pM expected %pM\n",
5075                            common->mld_mac_addr,
5076                            assoc_data->ap_addr);
5077                     goto abandon_assoc;
5078                 }
5079             }
5080         }
5081 
5082         sdata->vif.cfg.aid = aid;
5083 
5084         if (!ieee80211_assoc_success(sdata, mgmt, elems,
5085                          elem_start, elem_len)) {
5086             /* oops -- internal error -- send timeout for now */
5087             ieee80211_destroy_assoc_data(sdata, ASSOC_TIMEOUT);
5088             goto notify_driver;
5089         }
5090         event.u.mlme.status = MLME_SUCCESS;
5091         drv_event_callback(sdata->local, sdata, &event);
5092         sdata_info(sdata, "associated\n");
5093 
5094         info.success = 1;
5095     }
5096 
5097     for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
5098         struct ieee80211_link_data *link;
5099 
5100         link = sdata_dereference(sdata->link[link_id], sdata);
5101         if (!link)
5102             continue;
5103         if (!assoc_data->link[link_id].bss)
5104             continue;
5105         resp.links[link_id].bss = assoc_data->link[link_id].bss;
5106         resp.links[link_id].addr = link->conf->addr;
5107 
5108         /* get uapsd queues configuration - same for all links */
5109         resp.uapsd_queues = 0;
5110         for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
5111             if (link->tx_conf[ac].uapsd)
5112                 resp.uapsd_queues |= ieee80211_ac_to_qos_mask[ac];
5113     }
5114 
5115     ieee80211_destroy_assoc_data(sdata,
5116                      status_code == WLAN_STATUS_SUCCESS ?
5117                     ASSOC_SUCCESS :
5118                     ASSOC_REJECTED);
5119 
5120     resp.buf = (u8 *)mgmt;
5121     resp.len = len;
5122     resp.req_ies = ifmgd->assoc_req_ies;
5123     resp.req_ies_len = ifmgd->assoc_req_ies_len;
5124     if (sdata->vif.valid_links)
5125         resp.ap_mld_addr = assoc_data->ap_addr;
5126     cfg80211_rx_assoc_resp(sdata->dev, &resp);
5127 notify_driver:
5128     drv_mgd_complete_tx(sdata->local, sdata, &info);
5129     kfree(elems);
5130     return;
5131 abandon_assoc:
5132     ieee80211_destroy_assoc_data(sdata, ASSOC_ABANDON);
5133     goto notify_driver;
5134 }
5135 
5136 static void ieee80211_rx_bss_info(struct ieee80211_link_data *link,
5137                   struct ieee80211_mgmt *mgmt, size_t len,
5138                   struct ieee80211_rx_status *rx_status)
5139 {
5140     struct ieee80211_sub_if_data *sdata = link->sdata;
5141     struct ieee80211_local *local = sdata->local;
5142     struct ieee80211_bss *bss;
5143     struct ieee80211_channel *channel;
5144 
5145     sdata_assert_lock(sdata);
5146 
5147     channel = ieee80211_get_channel_khz(local->hw.wiphy,
5148                     ieee80211_rx_status_to_khz(rx_status));
5149     if (!channel)
5150         return;
5151 
5152     bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, channel);
5153     if (bss) {
5154         link->conf->beacon_rate = bss->beacon_rate;
5155         ieee80211_rx_bss_put(local, bss);
5156     }
5157 }
5158 
5159 
5160 static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_link_data *link,
5161                      struct sk_buff *skb)
5162 {
5163     struct ieee80211_sub_if_data *sdata = link->sdata;
5164     struct ieee80211_mgmt *mgmt = (void *)skb->data;
5165     struct ieee80211_if_managed *ifmgd;
5166     struct ieee80211_rx_status *rx_status = (void *) skb->cb;
5167     struct ieee80211_channel *channel;
5168     size_t baselen, len = skb->len;
5169 
5170     ifmgd = &sdata->u.mgd;
5171 
5172     sdata_assert_lock(sdata);
5173 
5174     /*
5175      * According to Draft P802.11ax D6.0 clause 26.17.2.3.2:
5176      * "If a 6 GHz AP receives a Probe Request frame  and responds with
5177      * a Probe Response frame [..], the Address 1 field of the Probe
5178      * Response frame shall be set to the broadcast address [..]"
5179      * So, on 6GHz band we should also accept broadcast responses.
5180      */
5181     channel = ieee80211_get_channel(sdata->local->hw.wiphy,
5182                     rx_status->freq);
5183     if (!channel)
5184         return;
5185 
5186     if (!ether_addr_equal(mgmt->da, sdata->vif.addr) &&
5187         (channel->band != NL80211_BAND_6GHZ ||
5188          !is_broadcast_ether_addr(mgmt->da)))
5189         return; /* ignore ProbeResp to foreign address */
5190 
5191     baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
5192     if (baselen > len)
5193         return;
5194 
5195     ieee80211_rx_bss_info(link, mgmt, len, rx_status);
5196 
5197     if (ifmgd->associated &&
5198         ether_addr_equal(mgmt->bssid, link->u.mgd.bssid))
5199         ieee80211_reset_ap_probe(sdata);
5200 }
5201 
5202 /*
5203  * This is the canonical list of information elements we care about,
5204  * the filter code also gives us all changes to the Microsoft OUI
5205  * (00:50:F2) vendor IE which is used for WMM which we need to track,
5206  * as well as the DTPC IE (part of the Cisco OUI) used for signaling
5207  * changes to requested client power.
5208  *
5209  * We implement beacon filtering in software since that means we can
5210  * avoid processing the frame here and in cfg80211, and userspace
5211  * will not be able to tell whether the hardware supports it or not.
5212  *
5213  * XXX: This list needs to be dynamic -- userspace needs to be able to
5214  *  add items it requires. It also needs to be able to tell us to
5215  *  look out for other vendor IEs.
5216  */
5217 static const u64 care_about_ies =
5218     (1ULL << WLAN_EID_COUNTRY) |
5219     (1ULL << WLAN_EID_ERP_INFO) |
5220     (1ULL << WLAN_EID_CHANNEL_SWITCH) |
5221     (1ULL << WLAN_EID_PWR_CONSTRAINT) |
5222     (1ULL << WLAN_EID_HT_CAPABILITY) |
5223     (1ULL << WLAN_EID_HT_OPERATION) |
5224     (1ULL << WLAN_EID_EXT_CHANSWITCH_ANN);
5225 
5226 static void ieee80211_handle_beacon_sig(struct ieee80211_link_data *link,
5227                     struct ieee80211_if_managed *ifmgd,
5228                     struct ieee80211_bss_conf *bss_conf,
5229                     struct ieee80211_local *local,
5230                     struct ieee80211_rx_status *rx_status)
5231 {
5232     struct ieee80211_sub_if_data *sdata = link->sdata;
5233 
5234     /* Track average RSSI from the Beacon frames of the current AP */
5235 
5236     if (!link->u.mgd.tracking_signal_avg) {
5237         link->u.mgd.tracking_signal_avg = true;
5238         ewma_beacon_signal_init(&link->u.mgd.ave_beacon_signal);
5239         link->u.mgd.last_cqm_event_signal = 0;
5240         link->u.mgd.count_beacon_signal = 1;
5241         link->u.mgd.last_ave_beacon_signal = 0;
5242     } else {
5243         link->u.mgd.count_beacon_signal++;
5244     }
5245 
5246     ewma_beacon_signal_add(&link->u.mgd.ave_beacon_signal,
5247                    -rx_status->signal);
5248 
5249     if (ifmgd->rssi_min_thold != ifmgd->rssi_max_thold &&
5250         link->u.mgd.count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) {
5251         int sig = -ewma_beacon_signal_read(&link->u.mgd.ave_beacon_signal);
5252         int last_sig = link->u.mgd.last_ave_beacon_signal;
5253         struct ieee80211_event event = {
5254             .type = RSSI_EVENT,
5255         };
5256 
5257         /*
5258          * if signal crosses either of the boundaries, invoke callback
5259          * with appropriate parameters
5260          */
5261         if (sig > ifmgd->rssi_max_thold &&
5262             (last_sig <= ifmgd->rssi_min_thold || last_sig == 0)) {
5263             link->u.mgd.last_ave_beacon_signal = sig;
5264             event.u.rssi.data = RSSI_EVENT_HIGH;
5265             drv_event_callback(local, sdata, &event);
5266         } else if (sig < ifmgd->rssi_min_thold &&
5267                (last_sig >= ifmgd->rssi_max_thold ||
5268                last_sig == 0)) {
5269             link->u.mgd.last_ave_beacon_signal = sig;
5270             event.u.rssi.data = RSSI_EVENT_LOW;
5271             drv_event_callback(local, sdata, &event);
5272         }
5273     }
5274 
5275     if (bss_conf->cqm_rssi_thold &&
5276         link->u.mgd.count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT &&
5277         !(sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) {
5278         int sig = -ewma_beacon_signal_read(&link->u.mgd.ave_beacon_signal);
5279         int last_event = link->u.mgd.last_cqm_event_signal;
5280         int thold = bss_conf->cqm_rssi_thold;
5281         int hyst = bss_conf->cqm_rssi_hyst;
5282 
5283         if (sig < thold &&
5284             (last_event == 0 || sig < last_event - hyst)) {
5285             link->u.mgd.last_cqm_event_signal = sig;
5286             ieee80211_cqm_rssi_notify(
5287                 &sdata->vif,
5288                 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
5289                 sig, GFP_KERNEL);
5290         } else if (sig > thold &&
5291                (last_event == 0 || sig > last_event + hyst)) {
5292             link->u.mgd.last_cqm_event_signal = sig;
5293             ieee80211_cqm_rssi_notify(
5294                 &sdata->vif,
5295                 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
5296                 sig, GFP_KERNEL);
5297         }
5298     }
5299 
5300     if (bss_conf->cqm_rssi_low &&
5301         link->u.mgd.count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT) {
5302         int sig = -ewma_beacon_signal_read(&link->u.mgd.ave_beacon_signal);
5303         int last_event = link->u.mgd.last_cqm_event_signal;
5304         int low = bss_conf->cqm_rssi_low;
5305         int high = bss_conf->cqm_rssi_high;
5306 
5307         if (sig < low &&
5308             (last_event == 0 || last_event >= low)) {
5309             link->u.mgd.last_cqm_event_signal = sig;
5310             ieee80211_cqm_rssi_notify(
5311                 &sdata->vif,
5312                 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
5313                 sig, GFP_KERNEL);
5314         } else if (sig > high &&
5315                (last_event == 0 || last_event <= high)) {
5316             link->u.mgd.last_cqm_event_signal = sig;
5317             ieee80211_cqm_rssi_notify(
5318                 &sdata->vif,
5319                 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
5320                 sig, GFP_KERNEL);
5321         }
5322     }
5323 }
5324 
5325 static bool ieee80211_rx_our_beacon(const u8 *tx_bssid,
5326                     struct cfg80211_bss *bss)
5327 {
5328     if (ether_addr_equal(tx_bssid, bss->bssid))
5329         return true;
5330     if (!bss->transmitted_bss)
5331         return false;
5332     return ether_addr_equal(tx_bssid, bss->transmitted_bss->bssid);
5333 }
5334 
5335 static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
5336                      struct ieee80211_hdr *hdr, size_t len,
5337                      struct ieee80211_rx_status *rx_status)
5338 {
5339     struct ieee80211_sub_if_data *sdata = link->sdata;
5340     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
5341     struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
5342     struct ieee80211_vif_cfg *vif_cfg = &sdata->vif.cfg;
5343     struct ieee80211_mgmt *mgmt = (void *) hdr;
5344     size_t baselen;
5345     struct ieee802_11_elems *elems;
5346     struct ieee80211_local *local = sdata->local;
5347     struct ieee80211_chanctx_conf *chanctx_conf;
5348     struct ieee80211_channel *chan;
5349     struct link_sta_info *link_sta;
5350     struct sta_info *sta;
5351     u32 changed = 0;
5352     bool erp_valid;
5353     u8 erp_value = 0;
5354     u32 ncrc = 0;
5355     u8 *bssid, *variable = mgmt->u.beacon.variable;
5356     u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
5357 
5358     sdata_assert_lock(sdata);
5359 
5360     /* Process beacon from the current BSS */
5361     bssid = ieee80211_get_bssid(hdr, len, sdata->vif.type);
5362     if (ieee80211_is_s1g_beacon(mgmt->frame_control)) {
5363         struct ieee80211_ext *ext = (void *) mgmt;
5364 
5365         if (ieee80211_is_s1g_short_beacon(ext->frame_control))
5366             variable = ext->u.s1g_short_beacon.variable;
5367         else
5368             variable = ext->u.s1g_beacon.variable;
5369     }
5370 
5371     baselen = (u8 *) variable - (u8 *) mgmt;
5372     if (baselen > len)
5373         return;
5374 
5375     rcu_read_lock();
5376     chanctx_conf = rcu_dereference(link->conf->chanctx_conf);
5377     if (!chanctx_conf) {
5378         rcu_read_unlock();
5379         return;
5380     }
5381 
5382     if (ieee80211_rx_status_to_khz(rx_status) !=
5383         ieee80211_channel_to_khz(chanctx_conf->def.chan)) {
5384         rcu_read_unlock();
5385         return;
5386     }
5387     chan = chanctx_conf->def.chan;
5388     rcu_read_unlock();
5389 
5390     if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon &&
5391         !WARN_ON(sdata->vif.valid_links) &&
5392         ieee80211_rx_our_beacon(bssid, ifmgd->assoc_data->link[0].bss)) {
5393         elems = ieee802_11_parse_elems(variable, len - baselen, false,
5394                            ifmgd->assoc_data->link[0].bss);
5395         if (!elems)
5396             return;
5397 
5398         ieee80211_rx_bss_info(link, mgmt, len, rx_status);
5399 
5400         if (elems->dtim_period)
5401             link->u.mgd.dtim_period = elems->dtim_period;
5402         link->u.mgd.have_beacon = true;
5403         ifmgd->assoc_data->need_beacon = false;
5404         if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) {
5405             link->conf->sync_tsf =
5406                 le64_to_cpu(mgmt->u.beacon.timestamp);
5407             link->conf->sync_device_ts =
5408                 rx_status->device_timestamp;
5409             link->conf->sync_dtim_count = elems->dtim_count;
5410         }
5411 
5412         if (elems->mbssid_config_ie)
5413             bss_conf->profile_periodicity =
5414                 elems->mbssid_config_ie->profile_periodicity;
5415         else
5416             bss_conf->profile_periodicity = 0;
5417 
5418         if (elems->ext_capab_len >= 11 &&
5419             (elems->ext_capab[10] & WLAN_EXT_CAPA11_EMA_SUPPORT))
5420             bss_conf->ema_ap = true;
5421         else
5422             bss_conf->ema_ap = false;
5423 
5424         /* continue assoc process */
5425         ifmgd->assoc_data->timeout = jiffies;
5426         ifmgd->assoc_data->timeout_started = true;
5427         run_again(sdata, ifmgd->assoc_data->timeout);
5428         kfree(elems);
5429         return;
5430     }
5431 
5432     if (!ifmgd->associated ||
5433         !ieee80211_rx_our_beacon(bssid, link->u.mgd.bss))
5434         return;
5435     bssid = link->u.mgd.bssid;
5436 
5437     if (!(rx_status->flag & RX_FLAG_NO_SIGNAL_VAL))
5438         ieee80211_handle_beacon_sig(link, ifmgd, bss_conf,
5439                         local, rx_status);
5440 
5441     if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL) {
5442         mlme_dbg_ratelimited(sdata,
5443                      "cancelling AP probe due to a received beacon\n");
5444         ieee80211_reset_ap_probe(sdata);
5445     }
5446 
5447     /*
5448      * Push the beacon loss detection into the future since
5449      * we are processing a beacon from the AP just now.
5450      */
5451     ieee80211_sta_reset_beacon_monitor(sdata);
5452 
5453     /* TODO: CRC urrently not calculated on S1G Beacon Compatibility
5454      * element (which carries the beacon interval). Don't forget to add a
5455      * bit to care_about_ies[] above if mac80211 is interested in a
5456      * changing S1G element.
5457      */
5458     if (!ieee80211_is_s1g_beacon(hdr->frame_control))
5459         ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
5460     elems = ieee802_11_parse_elems_crc(variable, len - baselen,
5461                        false, care_about_ies, ncrc,
5462                        link->u.mgd.bss);
5463     if (!elems)
5464         return;
5465     ncrc = elems->crc;
5466 
5467     if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) &&
5468         ieee80211_check_tim(elems->tim, elems->tim_len, vif_cfg->aid)) {
5469         if (local->hw.conf.dynamic_ps_timeout > 0) {
5470             if (local->hw.conf.flags & IEEE80211_CONF_PS) {
5471                 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
5472                 ieee80211_hw_config(local,
5473                             IEEE80211_CONF_CHANGE_PS);
5474             }
5475             ieee80211_send_nullfunc(local, sdata, false);
5476         } else if (!local->pspolling && sdata->u.mgd.powersave) {
5477             local->pspolling = true;
5478 
5479             /*
5480              * Here is assumed that the driver will be
5481              * able to send ps-poll frame and receive a
5482              * response even though power save mode is
5483              * enabled, but some drivers might require
5484              * to disable power save here. This needs
5485              * to be investigated.
5486              */
5487             ieee80211_send_pspoll(local, sdata);
5488         }
5489     }
5490 
5491     if (sdata->vif.p2p ||
5492         sdata->vif.driver_flags & IEEE80211_VIF_GET_NOA_UPDATE) {
5493         struct ieee80211_p2p_noa_attr noa = {};
5494         int ret;
5495 
5496         ret = cfg80211_get_p2p_attr(variable,
5497                         len - baselen,
5498                         IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
5499                         (u8 *) &noa, sizeof(noa));
5500         if (ret >= 2) {
5501             if (link->u.mgd.p2p_noa_index != noa.index) {
5502                 /* valid noa_attr and index changed */
5503                 link->u.mgd.p2p_noa_index = noa.index;
5504                 memcpy(&bss_conf->p2p_noa_attr, &noa, sizeof(noa));
5505                 changed |= BSS_CHANGED_P2P_PS;
5506                 /*
5507                  * make sure we update all information, the CRC
5508                  * mechanism doesn't look at P2P attributes.
5509                  */
5510                 link->u.mgd.beacon_crc_valid = false;
5511             }
5512         } else if (link->u.mgd.p2p_noa_index != -1) {
5513             /* noa_attr not found and we had valid noa_attr before */
5514             link->u.mgd.p2p_noa_index = -1;
5515             memset(&bss_conf->p2p_noa_attr, 0, sizeof(bss_conf->p2p_noa_attr));
5516             changed |= BSS_CHANGED_P2P_PS;
5517             link->u.mgd.beacon_crc_valid = false;
5518         }
5519     }
5520 
5521     if (link->u.mgd.csa_waiting_bcn)
5522         ieee80211_chswitch_post_beacon(link);
5523 
5524     /*
5525      * Update beacon timing and dtim count on every beacon appearance. This
5526      * will allow the driver to use the most updated values. Do it before
5527      * comparing this one with last received beacon.
5528      * IMPORTANT: These parameters would possibly be out of sync by the time
5529      * the driver will use them. The synchronized view is currently
5530      * guaranteed only in certain callbacks.
5531      */
5532     if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY) &&
5533         !ieee80211_is_s1g_beacon(hdr->frame_control)) {
5534         link->conf->sync_tsf =
5535             le64_to_cpu(mgmt->u.beacon.timestamp);
5536         link->conf->sync_device_ts =
5537             rx_status->device_timestamp;
5538         link->conf->sync_dtim_count = elems->dtim_count;
5539     }
5540 
5541     if ((ncrc == link->u.mgd.beacon_crc && link->u.mgd.beacon_crc_valid) ||
5542         ieee80211_is_s1g_short_beacon(mgmt->frame_control))
5543         goto free;
5544     link->u.mgd.beacon_crc = ncrc;
5545     link->u.mgd.beacon_crc_valid = true;
5546 
5547     ieee80211_rx_bss_info(link, mgmt, len, rx_status);
5548 
5549     ieee80211_sta_process_chanswitch(link, rx_status->mactime,
5550                      rx_status->device_timestamp,
5551                      elems, true);
5552 
5553     if (!link->u.mgd.disable_wmm_tracking &&
5554         ieee80211_sta_wmm_params(local, link, elems->wmm_param,
5555                      elems->wmm_param_len,
5556                      elems->mu_edca_param_set))
5557         changed |= BSS_CHANGED_QOS;
5558 
5559     /*
5560      * If we haven't had a beacon before, tell the driver about the
5561      * DTIM period (and beacon timing if desired) now.
5562      */
5563     if (!link->u.mgd.have_beacon) {
5564         /* a few bogus AP send dtim_period = 0 or no TIM IE */
5565         bss_conf->dtim_period = elems->dtim_period ?: 1;
5566 
5567         changed |= BSS_CHANGED_BEACON_INFO;
5568         link->u.mgd.have_beacon = true;
5569 
5570         mutex_lock(&local->iflist_mtx);
5571         ieee80211_recalc_ps(local);
5572         mutex_unlock(&local->iflist_mtx);
5573 
5574         ieee80211_recalc_ps_vif(sdata);
5575     }
5576 
5577     if (elems->erp_info) {
5578         erp_valid = true;
5579         erp_value = elems->erp_info[0];
5580     } else {
5581         erp_valid = false;
5582     }
5583 
5584     if (!ieee80211_is_s1g_beacon(hdr->frame_control))
5585         changed |= ieee80211_handle_bss_capability(link,
5586                 le16_to_cpu(mgmt->u.beacon.capab_info),
5587                 erp_valid, erp_value);
5588 
5589     mutex_lock(&local->sta_mtx);
5590     sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr);
5591     if (WARN_ON(!sta)) {
5592         mutex_unlock(&local->sta_mtx);
5593         goto free;
5594     }
5595     link_sta = rcu_dereference_protected(sta->link[link->link_id],
5596                          lockdep_is_held(&local->sta_mtx));
5597     if (WARN_ON(!link_sta)) {
5598         mutex_unlock(&local->sta_mtx);
5599         goto free;
5600     }
5601 
5602     changed |= ieee80211_recalc_twt_req(link, link_sta, elems);
5603 
5604     if (ieee80211_config_bw(link, elems->ht_cap_elem,
5605                 elems->vht_cap_elem, elems->ht_operation,
5606                 elems->vht_operation, elems->he_operation,
5607                 elems->eht_operation,
5608                 elems->s1g_oper, bssid, &changed)) {
5609         mutex_unlock(&local->sta_mtx);
5610         sdata_info(sdata,
5611                "failed to follow AP %pM bandwidth change, disconnect\n",
5612                bssid);
5613         ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
5614                        WLAN_REASON_DEAUTH_LEAVING,
5615                        true, deauth_buf);
5616         ieee80211_report_disconnect(sdata, deauth_buf,
5617                         sizeof(deauth_buf), true,
5618                         WLAN_REASON_DEAUTH_LEAVING,
5619                         false);
5620         goto free;
5621     }
5622 
5623     if (sta && elems->opmode_notif)
5624         ieee80211_vht_handle_opmode(sdata, link_sta,
5625                         *elems->opmode_notif,
5626                         rx_status->band);
5627     mutex_unlock(&local->sta_mtx);
5628 
5629     changed |= ieee80211_handle_pwr_constr(link, chan, mgmt,
5630                            elems->country_elem,
5631                            elems->country_elem_len,
5632                            elems->pwr_constr_elem,
5633                            elems->cisco_dtpc_elem);
5634 
5635     ieee80211_link_info_change_notify(sdata, link, changed);
5636 free:
5637     kfree(elems);
5638 }
5639 
5640 void ieee80211_sta_rx_queued_ext(struct ieee80211_sub_if_data *sdata,
5641                  struct sk_buff *skb)
5642 {
5643     struct ieee80211_link_data *link = &sdata->deflink;
5644     struct ieee80211_rx_status *rx_status;
5645     struct ieee80211_hdr *hdr;
5646     u16 fc;
5647 
5648     rx_status = (struct ieee80211_rx_status *) skb->cb;
5649     hdr = (struct ieee80211_hdr *) skb->data;
5650     fc = le16_to_cpu(hdr->frame_control);
5651 
5652     sdata_lock(sdata);
5653     switch (fc & IEEE80211_FCTL_STYPE) {
5654     case IEEE80211_STYPE_S1G_BEACON:
5655         ieee80211_rx_mgmt_beacon(link, hdr, skb->len, rx_status);
5656         break;
5657     }
5658     sdata_unlock(sdata);
5659 }
5660 
5661 void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
5662                   struct sk_buff *skb)
5663 {
5664     struct ieee80211_link_data *link = &sdata->deflink;
5665     struct ieee80211_rx_status *rx_status;
5666     struct ieee80211_mgmt *mgmt;
5667     u16 fc;
5668     int ies_len;
5669 
5670     rx_status = (struct ieee80211_rx_status *) skb->cb;
5671     mgmt = (struct ieee80211_mgmt *) skb->data;
5672     fc = le16_to_cpu(mgmt->frame_control);
5673 
5674     sdata_lock(sdata);
5675 
5676     switch (fc & IEEE80211_FCTL_STYPE) {
5677     case IEEE80211_STYPE_BEACON:
5678         ieee80211_rx_mgmt_beacon(link, (void *)mgmt,
5679                      skb->len, rx_status);
5680         break;
5681     case IEEE80211_STYPE_PROBE_RESP:
5682         ieee80211_rx_mgmt_probe_resp(link, skb);
5683         break;
5684     case IEEE80211_STYPE_AUTH:
5685         ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len);
5686         break;
5687     case IEEE80211_STYPE_DEAUTH:
5688         ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
5689         break;
5690     case IEEE80211_STYPE_DISASSOC:
5691         ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
5692         break;
5693     case IEEE80211_STYPE_ASSOC_RESP:
5694     case IEEE80211_STYPE_REASSOC_RESP:
5695         ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len);
5696         break;
5697     case IEEE80211_STYPE_ACTION:
5698         if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) {
5699             struct ieee802_11_elems *elems;
5700 
5701             ies_len = skb->len -
5702                   offsetof(struct ieee80211_mgmt,
5703                        u.action.u.chan_switch.variable);
5704 
5705             if (ies_len < 0)
5706                 break;
5707 
5708             /* CSA IE cannot be overridden, no need for BSSID */
5709             elems = ieee802_11_parse_elems(
5710                     mgmt->u.action.u.chan_switch.variable,
5711                     ies_len, true, NULL);
5712 
5713             if (elems && !elems->parse_error)
5714                 ieee80211_sta_process_chanswitch(link,
5715                                  rx_status->mactime,
5716                                  rx_status->device_timestamp,
5717                                  elems, false);
5718             kfree(elems);
5719         } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
5720             struct ieee802_11_elems *elems;
5721 
5722             ies_len = skb->len -
5723                   offsetof(struct ieee80211_mgmt,
5724                        u.action.u.ext_chan_switch.variable);
5725 
5726             if (ies_len < 0)
5727                 break;
5728 
5729             /*
5730              * extended CSA IE can't be overridden, no need for
5731              * BSSID
5732              */
5733             elems = ieee802_11_parse_elems(
5734                     mgmt->u.action.u.ext_chan_switch.variable,
5735                     ies_len, true, NULL);
5736 
5737             if (elems && !elems->parse_error) {
5738                 /* for the handling code pretend it was an IE */
5739                 elems->ext_chansw_ie =
5740                     &mgmt->u.action.u.ext_chan_switch.data;
5741 
5742                 ieee80211_sta_process_chanswitch(link,
5743                                  rx_status->mactime,
5744                                  rx_status->device_timestamp,
5745                                  elems, false);
5746             }
5747 
5748             kfree(elems);
5749         }
5750         break;
5751     }
5752     sdata_unlock(sdata);
5753 }
5754 
5755 static void ieee80211_sta_timer(struct timer_list *t)
5756 {
5757     struct ieee80211_sub_if_data *sdata =
5758         from_timer(sdata, t, u.mgd.timer);
5759 
5760     ieee80211_queue_work(&sdata->local->hw, &sdata->work);
5761 }
5762 
5763 void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
5764                    u8 reason, bool tx)
5765 {
5766     u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
5767 
5768     ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason,
5769                    tx, frame_buf);
5770 
5771     ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
5772                     reason, false);
5773 }
5774 
5775 static int ieee80211_auth(struct ieee80211_sub_if_data *sdata)
5776 {
5777     struct ieee80211_local *local = sdata->local;
5778     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
5779     struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data;
5780     u32 tx_flags = 0;
5781     u16 trans = 1;
5782     u16 status = 0;
5783     struct ieee80211_prep_tx_info info = {
5784         .subtype = IEEE80211_STYPE_AUTH,
5785     };
5786 
5787     sdata_assert_lock(sdata);
5788 
5789     if (WARN_ON_ONCE(!auth_data))
5790         return -EINVAL;
5791 
5792     auth_data->tries++;
5793 
5794     if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) {
5795         sdata_info(sdata, "authentication with %pM timed out\n",
5796                auth_data->ap_addr);
5797 
5798         /*
5799          * Most likely AP is not in the range so remove the
5800          * bss struct for that AP.
5801          */
5802         cfg80211_unlink_bss(local->hw.wiphy, auth_data->bss);
5803 
5804         return -ETIMEDOUT;
5805     }
5806 
5807     if (auth_data->algorithm == WLAN_AUTH_SAE)
5808         info.duration = jiffies_to_msecs(IEEE80211_AUTH_TIMEOUT_SAE);
5809 
5810     drv_mgd_prepare_tx(local, sdata, &info);
5811 
5812     sdata_info(sdata, "send auth to %pM (try %d/%d)\n",
5813            auth_data->ap_addr, auth_data->tries,
5814            IEEE80211_AUTH_MAX_TRIES);
5815 
5816     auth_data->expected_transaction = 2;
5817 
5818     if (auth_data->algorithm == WLAN_AUTH_SAE) {
5819         trans = auth_data->sae_trans;
5820         status = auth_data->sae_status;
5821         auth_data->expected_transaction = trans;
5822     }
5823 
5824     if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
5825         tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
5826                IEEE80211_TX_INTFL_MLME_CONN_TX;
5827 
5828     ieee80211_send_auth(sdata, trans, auth_data->algorithm, status,
5829                 auth_data->data, auth_data->data_len,
5830                 auth_data->ap_addr, auth_data->ap_addr,
5831                 NULL, 0, 0, tx_flags);
5832 
5833     if (tx_flags == 0) {
5834         if (auth_data->algorithm == WLAN_AUTH_SAE)
5835             auth_data->timeout = jiffies +
5836                 IEEE80211_AUTH_TIMEOUT_SAE;
5837         else
5838             auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
5839     } else {
5840         auth_data->timeout =
5841             round_jiffies_up(jiffies + IEEE80211_AUTH_TIMEOUT_LONG);
5842     }
5843 
5844     auth_data->timeout_started = true;
5845     run_again(sdata, auth_data->timeout);
5846 
5847     return 0;
5848 }
5849 
5850 static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
5851 {
5852     struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
5853     struct ieee80211_local *local = sdata->local;
5854     int ret;
5855 
5856     sdata_assert_lock(sdata);
5857 
5858     assoc_data->tries++;
5859     if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) {
5860         sdata_info(sdata, "association with %pM timed out\n",
5861                assoc_data->ap_addr);
5862 
5863         /*
5864          * Most likely AP is not in the range so remove the
5865          * bss struct for that AP.
5866          */
5867         cfg80211_unlink_bss(local->hw.wiphy,
5868                     assoc_data->link[assoc_data->assoc_link_id].bss);
5869 
5870         return -ETIMEDOUT;
5871     }
5872 
5873     sdata_info(sdata, "associate with %pM (try %d/%d)\n",
5874            assoc_data->ap_addr, assoc_data->tries,
5875            IEEE80211_ASSOC_MAX_TRIES);
5876     ret = ieee80211_send_assoc(sdata);
5877     if (ret)
5878         return ret;
5879 
5880     if (!ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
5881         assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
5882         assoc_data->timeout_started = true;
5883         run_again(sdata, assoc_data->timeout);
5884     } else {
5885         assoc_data->timeout =
5886             round_jiffies_up(jiffies +
5887                      IEEE80211_ASSOC_TIMEOUT_LONG);
5888         assoc_data->timeout_started = true;
5889         run_again(sdata, assoc_data->timeout);
5890     }
5891 
5892     return 0;
5893 }
5894 
5895 void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata,
5896                   __le16 fc, bool acked)
5897 {
5898     struct ieee80211_local *local = sdata->local;
5899 
5900     sdata->u.mgd.status_fc = fc;
5901     sdata->u.mgd.status_acked = acked;
5902     sdata->u.mgd.status_received = true;
5903 
5904     ieee80211_queue_work(&local->hw, &sdata->work);
5905 }
5906 
5907 void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
5908 {
5909     struct ieee80211_local *local = sdata->local;
5910     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
5911 
5912     sdata_lock(sdata);
5913 
5914     if (ifmgd->status_received) {
5915         __le16 fc = ifmgd->status_fc;
5916         bool status_acked = ifmgd->status_acked;
5917 
5918         ifmgd->status_received = false;
5919         if (ifmgd->auth_data && ieee80211_is_auth(fc)) {
5920             if (status_acked) {
5921                 if (ifmgd->auth_data->algorithm ==
5922                     WLAN_AUTH_SAE)
5923                     ifmgd->auth_data->timeout =
5924                         jiffies +
5925                         IEEE80211_AUTH_TIMEOUT_SAE;
5926                 else
5927                     ifmgd->auth_data->timeout =
5928                         jiffies +
5929                         IEEE80211_AUTH_TIMEOUT_SHORT;
5930                 run_again(sdata, ifmgd->auth_data->timeout);
5931             } else {
5932                 ifmgd->auth_data->timeout = jiffies - 1;
5933             }
5934             ifmgd->auth_data->timeout_started = true;
5935         } else if (ifmgd->assoc_data &&
5936                (ieee80211_is_assoc_req(fc) ||
5937                 ieee80211_is_reassoc_req(fc))) {
5938             if (status_acked) {
5939                 ifmgd->assoc_data->timeout =
5940                     jiffies + IEEE80211_ASSOC_TIMEOUT_SHORT;
5941                 run_again(sdata, ifmgd->assoc_data->timeout);
5942             } else {
5943                 ifmgd->assoc_data->timeout = jiffies - 1;
5944             }
5945             ifmgd->assoc_data->timeout_started = true;
5946         }
5947     }
5948 
5949     if (ifmgd->auth_data && ifmgd->auth_data->timeout_started &&
5950         time_after(jiffies, ifmgd->auth_data->timeout)) {
5951         if (ifmgd->auth_data->done || ifmgd->auth_data->waiting) {
5952             /*
5953              * ok ... we waited for assoc or continuation but
5954              * userspace didn't do it, so kill the auth data
5955              */
5956             ieee80211_destroy_auth_data(sdata, false);
5957         } else if (ieee80211_auth(sdata)) {
5958             u8 ap_addr[ETH_ALEN];
5959             struct ieee80211_event event = {
5960                 .type = MLME_EVENT,
5961                 .u.mlme.data = AUTH_EVENT,
5962                 .u.mlme.status = MLME_TIMEOUT,
5963             };
5964 
5965             memcpy(ap_addr, ifmgd->auth_data->ap_addr, ETH_ALEN);
5966 
5967             ieee80211_destroy_auth_data(sdata, false);
5968 
5969             cfg80211_auth_timeout(sdata->dev, ap_addr);
5970             drv_event_callback(sdata->local, sdata, &event);
5971         }
5972     } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started)
5973         run_again(sdata, ifmgd->auth_data->timeout);
5974 
5975     if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started &&
5976         time_after(jiffies, ifmgd->assoc_data->timeout)) {
5977         if ((ifmgd->assoc_data->need_beacon &&
5978              !sdata->deflink.u.mgd.have_beacon) ||
5979             ieee80211_do_assoc(sdata)) {
5980             struct ieee80211_event event = {
5981                 .type = MLME_EVENT,
5982                 .u.mlme.data = ASSOC_EVENT,
5983                 .u.mlme.status = MLME_TIMEOUT,
5984             };
5985 
5986             ieee80211_destroy_assoc_data(sdata, ASSOC_TIMEOUT);
5987             drv_event_callback(sdata->local, sdata, &event);
5988         }
5989     } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started)
5990         run_again(sdata, ifmgd->assoc_data->timeout);
5991 
5992     if (ifmgd->flags & IEEE80211_STA_CONNECTION_POLL &&
5993         ifmgd->associated) {
5994         u8 *bssid = sdata->deflink.u.mgd.bssid;
5995         int max_tries;
5996 
5997         if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS))
5998             max_tries = max_nullfunc_tries;
5999         else
6000             max_tries = max_probe_tries;
6001 
6002         /* ACK received for nullfunc probing frame */
6003         if (!ifmgd->probe_send_count)
6004             ieee80211_reset_ap_probe(sdata);
6005         else if (ifmgd->nullfunc_failed) {
6006             if (ifmgd->probe_send_count < max_tries) {
6007                 mlme_dbg(sdata,
6008                      "No ack for nullfunc frame to AP %pM, try %d/%i\n",
6009                      bssid, ifmgd->probe_send_count,
6010                      max_tries);
6011                 ieee80211_mgd_probe_ap_send(sdata);
6012             } else {
6013                 mlme_dbg(sdata,
6014                      "No ack for nullfunc frame to AP %pM, disconnecting.\n",
6015                      bssid);
6016                 ieee80211_sta_connection_lost(sdata,
6017                     WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
6018                     false);
6019             }
6020         } else if (time_is_after_jiffies(ifmgd->probe_timeout))
6021             run_again(sdata, ifmgd->probe_timeout);
6022         else if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) {
6023             mlme_dbg(sdata,
6024                  "Failed to send nullfunc to AP %pM after %dms, disconnecting\n",
6025                  bssid, probe_wait_ms);
6026             ieee80211_sta_connection_lost(sdata,
6027                 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, false);
6028         } else if (ifmgd->probe_send_count < max_tries) {
6029             mlme_dbg(sdata,
6030                  "No probe response from AP %pM after %dms, try %d/%i\n",
6031                  bssid, probe_wait_ms,
6032                  ifmgd->probe_send_count, max_tries);
6033             ieee80211_mgd_probe_ap_send(sdata);
6034         } else {
6035             /*
6036              * We actually lost the connection ... or did we?
6037              * Let's make sure!
6038              */
6039             mlme_dbg(sdata,
6040                  "No probe response from AP %pM after %dms, disconnecting.\n",
6041                  bssid, probe_wait_ms);
6042 
6043             ieee80211_sta_connection_lost(sdata,
6044                 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, false);
6045         }
6046     }
6047 
6048     sdata_unlock(sdata);
6049 }
6050 
6051 static void ieee80211_sta_bcn_mon_timer(struct timer_list *t)
6052 {
6053     struct ieee80211_sub_if_data *sdata =
6054         from_timer(sdata, t, u.mgd.bcn_mon_timer);
6055 
6056     if (WARN_ON(sdata->vif.valid_links))
6057         return;
6058 
6059     if (sdata->vif.bss_conf.csa_active &&
6060         !sdata->deflink.u.mgd.csa_waiting_bcn)
6061         return;
6062 
6063     if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER)
6064         return;
6065 
6066     sdata->u.mgd.connection_loss = false;
6067     ieee80211_queue_work(&sdata->local->hw,
6068                  &sdata->u.mgd.beacon_connection_loss_work);
6069 }
6070 
6071 static void ieee80211_sta_conn_mon_timer(struct timer_list *t)
6072 {
6073     struct ieee80211_sub_if_data *sdata =
6074         from_timer(sdata, t, u.mgd.conn_mon_timer);
6075     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
6076     struct ieee80211_local *local = sdata->local;
6077     struct sta_info *sta;
6078     unsigned long timeout;
6079 
6080     if (WARN_ON(sdata->vif.valid_links))
6081         return;
6082 
6083     if (sdata->vif.bss_conf.csa_active &&
6084         !sdata->deflink.u.mgd.csa_waiting_bcn)
6085         return;
6086 
6087     sta = sta_info_get(sdata, sdata->vif.cfg.ap_addr);
6088     if (!sta)
6089         return;
6090 
6091     timeout = sta->deflink.status_stats.last_ack;
6092     if (time_before(sta->deflink.status_stats.last_ack, sta->deflink.rx_stats.last_rx))
6093         timeout = sta->deflink.rx_stats.last_rx;
6094     timeout += IEEE80211_CONNECTION_IDLE_TIME;
6095 
6096     /* If timeout is after now, then update timer to fire at
6097      * the later date, but do not actually probe at this time.
6098      */
6099     if (time_is_after_jiffies(timeout)) {
6100         mod_timer(&ifmgd->conn_mon_timer, round_jiffies_up(timeout));
6101         return;
6102     }
6103 
6104     ieee80211_queue_work(&local->hw, &ifmgd->monitor_work);
6105 }
6106 
6107 static void ieee80211_sta_monitor_work(struct work_struct *work)
6108 {
6109     struct ieee80211_sub_if_data *sdata =
6110         container_of(work, struct ieee80211_sub_if_data,
6111                  u.mgd.monitor_work);
6112 
6113     ieee80211_mgd_probe_ap(sdata, false);
6114 }
6115 
6116 static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
6117 {
6118     if (sdata->vif.type == NL80211_IFTYPE_STATION) {
6119         __ieee80211_stop_poll(sdata);
6120 
6121         /* let's probe the connection once */
6122         if (!ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
6123             ieee80211_queue_work(&sdata->local->hw,
6124                          &sdata->u.mgd.monitor_work);
6125     }
6126 }
6127 
6128 #ifdef CONFIG_PM
6129 void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata)
6130 {
6131     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
6132     u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
6133 
6134     sdata_lock(sdata);
6135 
6136     if (ifmgd->auth_data || ifmgd->assoc_data) {
6137         const u8 *ap_addr = ifmgd->auth_data ?
6138                 ifmgd->auth_data->ap_addr :
6139                 ifmgd->assoc_data->ap_addr;
6140 
6141         /*
6142          * If we are trying to authenticate / associate while suspending,
6143          * cfg80211 won't know and won't actually abort those attempts,
6144          * thus we need to do that ourselves.
6145          */
6146         ieee80211_send_deauth_disassoc(sdata, ap_addr, ap_addr,
6147                            IEEE80211_STYPE_DEAUTH,
6148                            WLAN_REASON_DEAUTH_LEAVING,
6149                            false, frame_buf);
6150         if (ifmgd->assoc_data)
6151             ieee80211_destroy_assoc_data(sdata, ASSOC_ABANDON);
6152         if (ifmgd->auth_data)
6153             ieee80211_destroy_auth_data(sdata, false);
6154         cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
6155                       IEEE80211_DEAUTH_FRAME_LEN,
6156                       false);
6157     }
6158 
6159     /* This is a bit of a hack - we should find a better and more generic
6160      * solution to this. Normally when suspending, cfg80211 will in fact
6161      * deauthenticate. However, it doesn't (and cannot) stop an ongoing
6162      * auth (not so important) or assoc (this is the problem) process.
6163      *
6164      * As a consequence, it can happen that we are in the process of both
6165      * associating and suspending, and receive an association response
6166      * after cfg80211 has checked if it needs to disconnect, but before
6167      * we actually set the flag to drop incoming frames. This will then
6168      * cause the workqueue flush to process the association response in
6169      * the suspend, resulting in a successful association just before it
6170      * tries to remove the interface from the driver, which now though
6171      * has a channel context assigned ... this results in issues.
6172      *
6173      * To work around this (for now) simply deauth here again if we're
6174      * now connected.
6175      */
6176     if (ifmgd->associated && !sdata->local->wowlan) {
6177         u8 bssid[ETH_ALEN];
6178         struct cfg80211_deauth_request req = {
6179             .reason_code = WLAN_REASON_DEAUTH_LEAVING,
6180             .bssid = bssid,
6181         };
6182 
6183         memcpy(bssid, sdata->vif.cfg.ap_addr, ETH_ALEN);
6184         ieee80211_mgd_deauth(sdata, &req);
6185     }
6186 
6187     sdata_unlock(sdata);
6188 }
6189 #endif
6190 
6191 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
6192 {
6193     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
6194 
6195     sdata_lock(sdata);
6196     if (!ifmgd->associated) {
6197         sdata_unlock(sdata);
6198         return;
6199     }
6200 
6201     if (sdata->flags & IEEE80211_SDATA_DISCONNECT_RESUME) {
6202         sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME;
6203         mlme_dbg(sdata, "driver requested disconnect after resume\n");
6204         ieee80211_sta_connection_lost(sdata,
6205                           WLAN_REASON_UNSPECIFIED,
6206                           true);
6207         sdata_unlock(sdata);
6208         return;
6209     }
6210 
6211     if (sdata->flags & IEEE80211_SDATA_DISCONNECT_HW_RESTART) {
6212         sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_HW_RESTART;
6213         mlme_dbg(sdata, "driver requested disconnect after hardware restart\n");
6214         ieee80211_sta_connection_lost(sdata,
6215                           WLAN_REASON_UNSPECIFIED,
6216                           true);
6217         sdata_unlock(sdata);
6218         return;
6219     }
6220 
6221     sdata_unlock(sdata);
6222 }
6223 
6224 static void ieee80211_request_smps_mgd_work(struct work_struct *work)
6225 {
6226     struct ieee80211_link_data *link =
6227         container_of(work, struct ieee80211_link_data,
6228                  u.mgd.request_smps_work);
6229 
6230     sdata_lock(link->sdata);
6231     __ieee80211_request_smps_mgd(link->sdata, link,
6232                      link->u.mgd.driver_smps_mode);
6233     sdata_unlock(link->sdata);
6234 }
6235 
6236 /* interface setup */
6237 void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
6238 {
6239     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
6240 
6241     INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work);
6242     INIT_WORK(&ifmgd->beacon_connection_loss_work,
6243           ieee80211_beacon_connection_loss_work);
6244     INIT_WORK(&ifmgd->csa_connection_drop_work,
6245           ieee80211_csa_connection_drop_work);
6246     INIT_DELAYED_WORK(&ifmgd->tdls_peer_del_work,
6247               ieee80211_tdls_peer_del_work);
6248     timer_setup(&ifmgd->timer, ieee80211_sta_timer, 0);
6249     timer_setup(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer, 0);
6250     timer_setup(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer, 0);
6251     INIT_DELAYED_WORK(&ifmgd->tx_tspec_wk,
6252               ieee80211_sta_handle_tspec_ac_params_wk);
6253 
6254     ifmgd->flags = 0;
6255     ifmgd->powersave = sdata->wdev.ps;
6256     ifmgd->uapsd_queues = sdata->local->hw.uapsd_queues;
6257     ifmgd->uapsd_max_sp_len = sdata->local->hw.uapsd_max_sp_len;
6258     /* Setup TDLS data */
6259     spin_lock_init(&ifmgd->teardown_lock);
6260     ifmgd->teardown_skb = NULL;
6261     ifmgd->orig_teardown_skb = NULL;
6262 }
6263 
6264 void ieee80211_mgd_setup_link(struct ieee80211_link_data *link)
6265 {
6266     struct ieee80211_sub_if_data *sdata = link->sdata;
6267     struct ieee80211_local *local = sdata->local;
6268     unsigned int link_id = link->link_id;
6269 
6270     link->u.mgd.p2p_noa_index = -1;
6271     link->u.mgd.conn_flags = 0;
6272     link->conf->bssid = link->u.mgd.bssid;
6273 
6274     INIT_WORK(&link->u.mgd.request_smps_work,
6275           ieee80211_request_smps_mgd_work);
6276     if (local->hw.wiphy->features & NL80211_FEATURE_DYNAMIC_SMPS)
6277         link->u.mgd.req_smps = IEEE80211_SMPS_AUTOMATIC;
6278     else
6279         link->u.mgd.req_smps = IEEE80211_SMPS_OFF;
6280 
6281     INIT_WORK(&link->u.mgd.chswitch_work, ieee80211_chswitch_work);
6282     timer_setup(&link->u.mgd.chswitch_timer, ieee80211_chswitch_timer, 0);
6283 
6284     if (sdata->u.mgd.assoc_data)
6285         ether_addr_copy(link->conf->addr,
6286                 sdata->u.mgd.assoc_data->link[link_id].addr);
6287 }
6288 
6289 /* scan finished notification */
6290 void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
6291 {
6292     struct ieee80211_sub_if_data *sdata;
6293 
6294     /* Restart STA timers */
6295     rcu_read_lock();
6296     list_for_each_entry_rcu(sdata, &local->interfaces, list) {
6297         if (ieee80211_sdata_running(sdata))
6298             ieee80211_restart_sta_timer(sdata);
6299     }
6300     rcu_read_unlock();
6301 }
6302 
6303 static bool ieee80211_get_dtim(const struct cfg80211_bss_ies *ies,
6304                    u8 *dtim_count, u8 *dtim_period)
6305 {
6306     const u8 *tim_ie = cfg80211_find_ie(WLAN_EID_TIM, ies->data, ies->len);
6307     const u8 *idx_ie = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX, ies->data,
6308                      ies->len);
6309     const struct ieee80211_tim_ie *tim = NULL;
6310     const struct ieee80211_bssid_index *idx;
6311     bool valid = tim_ie && tim_ie[1] >= 2;
6312 
6313     if (valid)
6314         tim = (void *)(tim_ie + 2);
6315 
6316     if (dtim_count)
6317         *dtim_count = valid ? tim->dtim_count : 0;
6318 
6319     if (dtim_period)
6320         *dtim_period = valid ? tim->dtim_period : 0;
6321 
6322     /* Check if value is overridden by non-transmitted profile */
6323     if (!idx_ie || idx_ie[1] < 3)
6324         return valid;
6325 
6326     idx = (void *)(idx_ie + 2);
6327 
6328     if (dtim_count)
6329         *dtim_count = idx->dtim_count;
6330 
6331     if (dtim_period)
6332         *dtim_period = idx->dtim_period;
6333 
6334     return true;
6335 }
6336 
6337 static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
6338                      struct cfg80211_bss *cbss, s8 link_id,
6339                      const u8 *ap_mld_addr, bool assoc,
6340                      bool override)
6341 {
6342     struct ieee80211_local *local = sdata->local;
6343     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
6344     struct ieee80211_bss *bss = (void *)cbss->priv;
6345     struct sta_info *new_sta = NULL;
6346     struct ieee80211_link_data *link;
6347     bool have_sta = false;
6348     bool mlo;
6349     int err;
6350 
6351     if (link_id >= 0) {
6352         mlo = true;
6353         if (WARN_ON(!ap_mld_addr))
6354             return -EINVAL;
6355         err = ieee80211_vif_set_links(sdata, BIT(link_id));
6356     } else {
6357         if (WARN_ON(ap_mld_addr))
6358             return -EINVAL;
6359         ap_mld_addr = cbss->bssid;
6360         err = ieee80211_vif_set_links(sdata, 0);
6361         link_id = 0;
6362         mlo = false;
6363     }
6364 
6365     if (err)
6366         return err;
6367 
6368     link = sdata_dereference(sdata->link[link_id], sdata);
6369     if (WARN_ON(!link)) {
6370         err = -ENOLINK;
6371         goto out_err;
6372     }
6373 
6374     if (mlo && !is_valid_ether_addr(link->conf->addr))
6375         eth_random_addr(link->conf->addr);
6376 
6377     if (WARN_ON(!ifmgd->auth_data && !ifmgd->assoc_data)) {
6378         err = -EINVAL;
6379         goto out_err;
6380     }
6381 
6382     /* If a reconfig is happening, bail out */
6383     if (local->in_reconfig) {
6384         err = -EBUSY;
6385         goto out_err;
6386     }
6387 
6388     if (assoc) {
6389         rcu_read_lock();
6390         have_sta = sta_info_get(sdata, ap_mld_addr);
6391         rcu_read_unlock();
6392     }
6393 
6394     if (!have_sta) {
6395         if (mlo)
6396             new_sta = sta_info_alloc_with_link(sdata, ap_mld_addr,
6397                                link_id, cbss->bssid,
6398                                GFP_KERNEL);
6399         else
6400             new_sta = sta_info_alloc(sdata, ap_mld_addr, GFP_KERNEL);
6401 
6402         if (!new_sta) {
6403             err = -ENOMEM;
6404             goto out_err;
6405         }
6406 
6407         new_sta->sta.mlo = mlo;
6408     }
6409 
6410     /*
6411      * Set up the information for the new channel before setting the
6412      * new channel. We can't - completely race-free - change the basic
6413      * rates bitmap and the channel (sband) that it refers to, but if
6414      * we set it up before we at least avoid calling into the driver's
6415      * bss_info_changed() method with invalid information (since we do
6416      * call that from changing the channel - only for IDLE and perhaps
6417      * some others, but ...).
6418      *
6419      * So to avoid that, just set up all the new information before the
6420      * channel, but tell the driver to apply it only afterwards, since
6421      * it might need the new channel for that.
6422      */
6423     if (new_sta) {
6424         const struct cfg80211_bss_ies *ies;
6425         struct link_sta_info *link_sta;
6426 
6427         rcu_read_lock();
6428         link_sta = rcu_dereference(new_sta->link[link_id]);
6429         if (WARN_ON(!link_sta)) {
6430             rcu_read_unlock();
6431             sta_info_free(local, new_sta);
6432             err = -EINVAL;
6433             goto out_err;
6434         }
6435 
6436         err = ieee80211_mgd_setup_link_sta(link, new_sta,
6437                            link_sta, cbss);
6438         if (err) {
6439             rcu_read_unlock();
6440             sta_info_free(local, new_sta);
6441             goto out_err;
6442         }
6443 
6444         memcpy(link->u.mgd.bssid, cbss->bssid, ETH_ALEN);
6445 
6446         /* set timing information */
6447         link->conf->beacon_int = cbss->beacon_interval;
6448         ies = rcu_dereference(cbss->beacon_ies);
6449         if (ies) {
6450             link->conf->sync_tsf = ies->tsf;
6451             link->conf->sync_device_ts =
6452                 bss->device_ts_beacon;
6453 
6454             ieee80211_get_dtim(ies,
6455                        &link->conf->sync_dtim_count,
6456                        NULL);
6457         } else if (!ieee80211_hw_check(&sdata->local->hw,
6458                            TIMING_BEACON_ONLY)) {
6459             ies = rcu_dereference(cbss->proberesp_ies);
6460             /* must be non-NULL since beacon IEs were NULL */
6461             link->conf->sync_tsf = ies->tsf;
6462             link->conf->sync_device_ts =
6463                 bss->device_ts_presp;
6464             link->conf->sync_dtim_count = 0;
6465         } else {
6466             link->conf->sync_tsf = 0;
6467             link->conf->sync_device_ts = 0;
6468             link->conf->sync_dtim_count = 0;
6469         }
6470         rcu_read_unlock();
6471     }
6472 
6473     if (new_sta || override) {
6474         err = ieee80211_prep_channel(sdata, link, cbss,
6475                          &link->u.mgd.conn_flags);
6476         if (err) {
6477             if (new_sta)
6478                 sta_info_free(local, new_sta);
6479             goto out_err;
6480         }
6481     }
6482 
6483     if (new_sta) {
6484         /*
6485          * tell driver about BSSID, basic rates and timing
6486          * this was set up above, before setting the channel
6487          */
6488         ieee80211_link_info_change_notify(sdata, link,
6489                           BSS_CHANGED_BSSID |
6490                           BSS_CHANGED_BASIC_RATES |
6491                           BSS_CHANGED_BEACON_INT);
6492 
6493         if (assoc)
6494             sta_info_pre_move_state(new_sta, IEEE80211_STA_AUTH);
6495 
6496         err = sta_info_insert(new_sta);
6497         new_sta = NULL;
6498         if (err) {
6499             sdata_info(sdata,
6500                    "failed to insert STA entry for the AP (error %d)\n",
6501                    err);
6502             goto out_err;
6503         }
6504     } else
6505         WARN_ON_ONCE(!ether_addr_equal(link->u.mgd.bssid, cbss->bssid));
6506 
6507     /* Cancel scan to ensure that nothing interferes with connection */
6508     if (local->scanning)
6509         ieee80211_scan_cancel(local);
6510 
6511     return 0;
6512 
6513 out_err:
6514     ieee80211_link_release_channel(&sdata->deflink);
6515     ieee80211_vif_set_links(sdata, 0);
6516     return err;
6517 }
6518 
6519 /* config hooks */
6520 int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
6521                struct cfg80211_auth_request *req)
6522 {
6523     struct ieee80211_local *local = sdata->local;
6524     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
6525     struct ieee80211_mgd_auth_data *auth_data;
6526     u16 auth_alg;
6527     int err;
6528     bool cont_auth;
6529 
6530     /* prepare auth data structure */
6531 
6532     switch (req->auth_type) {
6533     case NL80211_AUTHTYPE_OPEN_SYSTEM:
6534         auth_alg = WLAN_AUTH_OPEN;
6535         break;
6536     case NL80211_AUTHTYPE_SHARED_KEY:
6537         if (fips_enabled)
6538             return -EOPNOTSUPP;
6539         auth_alg = WLAN_AUTH_SHARED_KEY;
6540         break;
6541     case NL80211_AUTHTYPE_FT:
6542         auth_alg = WLAN_AUTH_FT;
6543         break;
6544     case NL80211_AUTHTYPE_NETWORK_EAP:
6545         auth_alg = WLAN_AUTH_LEAP;
6546         break;
6547     case NL80211_AUTHTYPE_SAE:
6548         auth_alg = WLAN_AUTH_SAE;
6549         break;
6550     case NL80211_AUTHTYPE_FILS_SK:
6551         auth_alg = WLAN_AUTH_FILS_SK;
6552         break;
6553     case NL80211_AUTHTYPE_FILS_SK_PFS:
6554         auth_alg = WLAN_AUTH_FILS_SK_PFS;
6555         break;
6556     case NL80211_AUTHTYPE_FILS_PK:
6557         auth_alg = WLAN_AUTH_FILS_PK;
6558         break;
6559     default:
6560         return -EOPNOTSUPP;
6561     }
6562 
6563     if (ifmgd->assoc_data)
6564         return -EBUSY;
6565 
6566     auth_data = kzalloc(sizeof(*auth_data) + req->auth_data_len +
6567                 req->ie_len, GFP_KERNEL);
6568     if (!auth_data)
6569         return -ENOMEM;
6570 
6571     memcpy(auth_data->ap_addr,
6572            req->ap_mld_addr ?: req->bss->bssid,
6573            ETH_ALEN);
6574     auth_data->bss = req->bss;
6575 
6576     if (req->auth_data_len >= 4) {
6577         if (req->auth_type == NL80211_AUTHTYPE_SAE) {
6578             __le16 *pos = (__le16 *) req->auth_data;
6579 
6580             auth_data->sae_trans = le16_to_cpu(pos[0]);
6581             auth_data->sae_status = le16_to_cpu(pos[1]);
6582         }
6583         memcpy(auth_data->data, req->auth_data + 4,
6584                req->auth_data_len - 4);
6585         auth_data->data_len += req->auth_data_len - 4;
6586     }
6587 
6588     /* Check if continuing authentication or trying to authenticate with the
6589      * same BSS that we were in the process of authenticating with and avoid
6590      * removal and re-addition of the STA entry in
6591      * ieee80211_prep_connection().
6592      */
6593     cont_auth = ifmgd->auth_data && req->bss == ifmgd->auth_data->bss;
6594 
6595     if (req->ie && req->ie_len) {
6596         memcpy(&auth_data->data[auth_data->data_len],
6597                req->ie, req->ie_len);
6598         auth_data->data_len += req->ie_len;
6599     }
6600 
6601     if (req->key && req->key_len) {
6602         auth_data->key_len = req->key_len;
6603         auth_data->key_idx = req->key_idx;
6604         memcpy(auth_data->key, req->key, req->key_len);
6605     }
6606 
6607     auth_data->algorithm = auth_alg;
6608 
6609     /* try to authenticate/probe */
6610 
6611     if (ifmgd->auth_data) {
6612         if (cont_auth && req->auth_type == NL80211_AUTHTYPE_SAE) {
6613             auth_data->peer_confirmed =
6614                 ifmgd->auth_data->peer_confirmed;
6615         }
6616         ieee80211_destroy_auth_data(sdata, cont_auth);
6617     }
6618 
6619     /* prep auth_data so we don't go into idle on disassoc */
6620     ifmgd->auth_data = auth_data;
6621 
6622     /* If this is continuation of an ongoing SAE authentication exchange
6623      * (i.e., request to send SAE Confirm) and the peer has already
6624      * confirmed, mark authentication completed since we are about to send
6625      * out SAE Confirm.
6626      */
6627     if (cont_auth && req->auth_type == NL80211_AUTHTYPE_SAE &&
6628         auth_data->peer_confirmed && auth_data->sae_trans == 2)
6629         ieee80211_mark_sta_auth(sdata);
6630 
6631     if (ifmgd->associated) {
6632         u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
6633 
6634         sdata_info(sdata,
6635                "disconnect from AP %pM for new auth to %pM\n",
6636                sdata->vif.cfg.ap_addr, auth_data->ap_addr);
6637         ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
6638                        WLAN_REASON_UNSPECIFIED,
6639                        false, frame_buf);
6640 
6641         ieee80211_report_disconnect(sdata, frame_buf,
6642                         sizeof(frame_buf), true,
6643                         WLAN_REASON_UNSPECIFIED,
6644                         false);
6645     }
6646 
6647     sdata_info(sdata, "authenticate with %pM\n", auth_data->ap_addr);
6648 
6649     /* needed for transmitting the auth frame(s) properly */
6650     memcpy(sdata->vif.cfg.ap_addr, auth_data->ap_addr, ETH_ALEN);
6651 
6652     err = ieee80211_prep_connection(sdata, req->bss, req->link_id,
6653                     req->ap_mld_addr, cont_auth, false);
6654     if (err)
6655         goto err_clear;
6656 
6657     err = ieee80211_auth(sdata);
6658     if (err) {
6659         sta_info_destroy_addr(sdata, auth_data->ap_addr);
6660         goto err_clear;
6661     }
6662 
6663     /* hold our own reference */
6664     cfg80211_ref_bss(local->hw.wiphy, auth_data->bss);
6665     return 0;
6666 
6667  err_clear:
6668     if (!sdata->vif.valid_links) {
6669         eth_zero_addr(sdata->deflink.u.mgd.bssid);
6670         ieee80211_link_info_change_notify(sdata, &sdata->deflink,
6671                           BSS_CHANGED_BSSID);
6672         mutex_lock(&sdata->local->mtx);
6673         ieee80211_link_release_channel(&sdata->deflink);
6674         mutex_unlock(&sdata->local->mtx);
6675     }
6676     ifmgd->auth_data = NULL;
6677     kfree(auth_data);
6678     return err;
6679 }
6680 
6681 static ieee80211_conn_flags_t
6682 ieee80211_setup_assoc_link(struct ieee80211_sub_if_data *sdata,
6683                struct ieee80211_mgd_assoc_data *assoc_data,
6684                struct cfg80211_assoc_request *req,
6685                ieee80211_conn_flags_t conn_flags,
6686                unsigned int link_id)
6687 {
6688     struct ieee80211_local *local = sdata->local;
6689     const struct cfg80211_bss_ies *beacon_ies;
6690     struct ieee80211_supported_band *sband;
6691     const struct element *ht_elem, *vht_elem;
6692     struct ieee80211_link_data *link;
6693     struct cfg80211_bss *cbss;
6694     struct ieee80211_bss *bss;
6695     bool is_5ghz, is_6ghz;
6696 
6697     cbss = assoc_data->link[link_id].bss;
6698     if (WARN_ON(!cbss))
6699         return 0;
6700 
6701     bss = (void *)cbss->priv;
6702 
6703     sband = local->hw.wiphy->bands[cbss->channel->band];
6704     if (WARN_ON(!sband))
6705         return 0;
6706 
6707     link = sdata_dereference(sdata->link[link_id], sdata);
6708     if (WARN_ON(!link))
6709         return 0;
6710 
6711     is_5ghz = cbss->channel->band == NL80211_BAND_5GHZ;
6712     is_6ghz = cbss->channel->band == NL80211_BAND_6GHZ;
6713 
6714     /* for MLO connections assume advertising all rates is OK */
6715     if (!req->ap_mld_addr) {
6716         assoc_data->supp_rates = bss->supp_rates;
6717         assoc_data->supp_rates_len = bss->supp_rates_len;
6718     }
6719 
6720     /* copy and link elems for the STA profile */
6721     if (req->links[link_id].elems_len) {
6722         memcpy(assoc_data->ie_pos, req->links[link_id].elems,
6723                req->links[link_id].elems_len);
6724         assoc_data->link[link_id].elems = assoc_data->ie_pos;
6725         assoc_data->link[link_id].elems_len = req->links[link_id].elems_len;
6726         assoc_data->ie_pos += req->links[link_id].elems_len;
6727     }
6728 
6729     rcu_read_lock();
6730     ht_elem = ieee80211_bss_get_elem(cbss, WLAN_EID_HT_OPERATION);
6731     if (ht_elem && ht_elem->datalen >= sizeof(struct ieee80211_ht_operation))
6732         assoc_data->link[link_id].ap_ht_param =
6733             ((struct ieee80211_ht_operation *)(ht_elem->data))->ht_param;
6734     else if (!is_6ghz)
6735         conn_flags |= IEEE80211_CONN_DISABLE_HT;
6736     vht_elem = ieee80211_bss_get_elem(cbss, WLAN_EID_VHT_CAPABILITY);
6737     if (vht_elem && vht_elem->datalen >= sizeof(struct ieee80211_vht_cap)) {
6738         memcpy(&assoc_data->link[link_id].ap_vht_cap, vht_elem->data,
6739                sizeof(struct ieee80211_vht_cap));
6740     } else if (is_5ghz) {
6741         link_info(link,
6742               "VHT capa missing/short, disabling VHT/HE/EHT\n");
6743         conn_flags |= IEEE80211_CONN_DISABLE_VHT |
6744                   IEEE80211_CONN_DISABLE_HE |
6745                   IEEE80211_CONN_DISABLE_EHT;
6746     }
6747     rcu_read_unlock();
6748 
6749     link->u.mgd.beacon_crc_valid = false;
6750     link->u.mgd.dtim_period = 0;
6751     link->u.mgd.have_beacon = false;
6752 
6753     /* override HT/VHT configuration only if the AP and we support it */
6754     if (!(conn_flags & IEEE80211_CONN_DISABLE_HT)) {
6755         struct ieee80211_sta_ht_cap sta_ht_cap;
6756 
6757         memcpy(&sta_ht_cap, &sband->ht_cap, sizeof(sta_ht_cap));
6758         ieee80211_apply_htcap_overrides(sdata, &sta_ht_cap);
6759     }
6760 
6761     rcu_read_lock();
6762     beacon_ies = rcu_dereference(cbss->beacon_ies);
6763     if (beacon_ies) {
6764         const struct element *elem;
6765         u8 dtim_count = 0;
6766 
6767         ieee80211_get_dtim(beacon_ies, &dtim_count,
6768                    &link->u.mgd.dtim_period);
6769 
6770         sdata->deflink.u.mgd.have_beacon = true;
6771 
6772         if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) {
6773             link->conf->sync_tsf = beacon_ies->tsf;
6774             link->conf->sync_device_ts = bss->device_ts_beacon;
6775             link->conf->sync_dtim_count = dtim_count;
6776         }
6777 
6778         elem = cfg80211_find_ext_elem(WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION,
6779                           beacon_ies->data, beacon_ies->len);
6780         if (elem && elem->datalen >= 3)
6781             link->conf->profile_periodicity = elem->data[2];
6782         else
6783             link->conf->profile_periodicity = 0;
6784 
6785         elem = cfg80211_find_elem(WLAN_EID_EXT_CAPABILITY,
6786                       beacon_ies->data, beacon_ies->len);
6787         if (elem && elem->datalen >= 11 &&
6788             (elem->data[10] & WLAN_EXT_CAPA11_EMA_SUPPORT))
6789             link->conf->ema_ap = true;
6790         else
6791             link->conf->ema_ap = false;
6792     }
6793     rcu_read_unlock();
6794 
6795     if (bss->corrupt_data) {
6796         char *corrupt_type = "data";
6797 
6798         if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_BEACON) {
6799             if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP)
6800                 corrupt_type = "beacon and probe response";
6801             else
6802                 corrupt_type = "beacon";
6803         } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP) {
6804             corrupt_type = "probe response";
6805         }
6806         sdata_info(sdata, "associating to AP %pM with corrupt %s\n",
6807                cbss->bssid, corrupt_type);
6808     }
6809 
6810     if (link->u.mgd.req_smps == IEEE80211_SMPS_AUTOMATIC) {
6811         if (sdata->u.mgd.powersave)
6812             link->smps_mode = IEEE80211_SMPS_DYNAMIC;
6813         else
6814             link->smps_mode = IEEE80211_SMPS_OFF;
6815     } else {
6816         link->smps_mode = link->u.mgd.req_smps;
6817     }
6818 
6819     return conn_flags;
6820 }
6821 
6822 int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
6823             struct cfg80211_assoc_request *req)
6824 {
6825     unsigned int assoc_link_id = req->link_id < 0 ? 0 : req->link_id;
6826     struct ieee80211_local *local = sdata->local;
6827     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
6828     struct ieee80211_mgd_assoc_data *assoc_data;
6829     const struct element *ssid_elem;
6830     struct ieee80211_vif_cfg *vif_cfg = &sdata->vif.cfg;
6831     ieee80211_conn_flags_t conn_flags = 0;
6832     struct ieee80211_link_data *link;
6833     struct cfg80211_bss *cbss;
6834     struct ieee80211_bss *bss;
6835     bool override;
6836     int i, err;
6837     size_t size = sizeof(*assoc_data) + req->ie_len;
6838 
6839     for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++)
6840         size += req->links[i].elems_len;
6841 
6842     if (req->ap_mld_addr) {
6843         for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) {
6844             if (!req->links[i].bss)
6845                 continue;
6846             if (i == assoc_link_id)
6847                 continue;
6848             /*
6849              * For now, support only a single link in MLO, we
6850              * don't have the necessary parsing of the multi-
6851              * link element in the association response, etc.
6852              */
6853             sdata_info(sdata,
6854                    "refusing MLO association with >1 links\n");
6855             return -EINVAL;
6856         }
6857     }
6858 
6859     assoc_data = kzalloc(size, GFP_KERNEL);
6860     if (!assoc_data)
6861         return -ENOMEM;
6862 
6863     cbss = req->link_id < 0 ? req->bss : req->links[req->link_id].bss;
6864 
6865     rcu_read_lock();
6866     ssid_elem = ieee80211_bss_get_elem(cbss, WLAN_EID_SSID);
6867     if (!ssid_elem || ssid_elem->datalen > sizeof(assoc_data->ssid)) {
6868         rcu_read_unlock();
6869         kfree(assoc_data);
6870         return -EINVAL;
6871     }
6872     memcpy(assoc_data->ssid, ssid_elem->data, ssid_elem->datalen);
6873     assoc_data->ssid_len = ssid_elem->datalen;
6874     memcpy(vif_cfg->ssid, assoc_data->ssid, assoc_data->ssid_len);
6875     vif_cfg->ssid_len = assoc_data->ssid_len;
6876     rcu_read_unlock();
6877 
6878     if (req->ap_mld_addr) {
6879         for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) {
6880             if (!req->links[i].bss)
6881                 continue;
6882             link = sdata_dereference(sdata->link[i], sdata);
6883             if (link)
6884                 ether_addr_copy(assoc_data->link[i].addr,
6885                         link->conf->addr);
6886             else
6887                 eth_random_addr(assoc_data->link[i].addr);
6888         }
6889     } else {
6890         memcpy(assoc_data->link[0].addr, sdata->vif.addr, ETH_ALEN);
6891     }
6892 
6893     assoc_data->s1g = cbss->channel->band == NL80211_BAND_S1GHZ;
6894 
6895     memcpy(assoc_data->ap_addr,
6896            req->ap_mld_addr ?: req->bss->bssid,
6897            ETH_ALEN);
6898 
6899     if (ifmgd->associated) {
6900         u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
6901 
6902         sdata_info(sdata,
6903                "disconnect from AP %pM for new assoc to %pM\n",
6904                sdata->vif.cfg.ap_addr, assoc_data->ap_addr);
6905         ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
6906                        WLAN_REASON_UNSPECIFIED,
6907                        false, frame_buf);
6908 
6909         ieee80211_report_disconnect(sdata, frame_buf,
6910                         sizeof(frame_buf), true,
6911                         WLAN_REASON_UNSPECIFIED,
6912                         false);
6913     }
6914 
6915     if (ifmgd->auth_data && !ifmgd->auth_data->done) {
6916         err = -EBUSY;
6917         goto err_free;
6918     }
6919 
6920     if (ifmgd->assoc_data) {
6921         err = -EBUSY;
6922         goto err_free;
6923     }
6924 
6925     if (ifmgd->auth_data) {
6926         bool match;
6927 
6928         /* keep sta info, bssid if matching */
6929         match = ether_addr_equal(ifmgd->auth_data->ap_addr,
6930                      assoc_data->ap_addr);
6931         ieee80211_destroy_auth_data(sdata, match);
6932     }
6933 
6934     /* prepare assoc data */
6935 
6936     bss = (void *)cbss->priv;
6937     assoc_data->wmm = bss->wmm_used &&
6938               (local->hw.queues >= IEEE80211_NUM_ACS);
6939 
6940     /*
6941      * IEEE802.11n does not allow TKIP/WEP as pairwise ciphers in HT mode.
6942      * We still associate in non-HT mode (11a/b/g) if any one of these
6943      * ciphers is configured as pairwise.
6944      * We can set this to true for non-11n hardware, that'll be checked
6945      * separately along with the peer capabilities.
6946      */
6947     for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) {
6948         if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 ||
6949             req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP ||
6950             req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) {
6951             conn_flags |= IEEE80211_CONN_DISABLE_HT;
6952             conn_flags |= IEEE80211_CONN_DISABLE_VHT;
6953             conn_flags |= IEEE80211_CONN_DISABLE_HE;
6954             conn_flags |= IEEE80211_CONN_DISABLE_EHT;
6955             netdev_info(sdata->dev,
6956                     "disabling HT/VHT/HE due to WEP/TKIP use\n");
6957         }
6958     }
6959 
6960     /* also disable HT/VHT/HE/EHT if the AP doesn't use WMM */
6961     if (!bss->wmm_used) {
6962         conn_flags |= IEEE80211_CONN_DISABLE_HT;
6963         conn_flags |= IEEE80211_CONN_DISABLE_VHT;
6964         conn_flags |= IEEE80211_CONN_DISABLE_HE;
6965         conn_flags |= IEEE80211_CONN_DISABLE_EHT;
6966         netdev_info(sdata->dev,
6967                 "disabling HT/VHT/HE as WMM/QoS is not supported by the AP\n");
6968     }
6969 
6970     if (req->flags & ASSOC_REQ_DISABLE_HT) {
6971         mlme_dbg(sdata, "HT disabled by flag, disabling HT/VHT/HE\n");
6972         conn_flags |= IEEE80211_CONN_DISABLE_HT;
6973         conn_flags |= IEEE80211_CONN_DISABLE_VHT;
6974         conn_flags |= IEEE80211_CONN_DISABLE_HE;
6975         conn_flags |= IEEE80211_CONN_DISABLE_EHT;
6976     }
6977 
6978     if (req->flags & ASSOC_REQ_DISABLE_VHT) {
6979         mlme_dbg(sdata, "VHT disabled by flag, disabling VHT\n");
6980         conn_flags |= IEEE80211_CONN_DISABLE_VHT;
6981     }
6982 
6983     if (req->flags & ASSOC_REQ_DISABLE_HE) {
6984         mlme_dbg(sdata, "HE disabled by flag, disabling HE/EHT\n");
6985         conn_flags |= IEEE80211_CONN_DISABLE_HE;
6986         conn_flags |= IEEE80211_CONN_DISABLE_EHT;
6987     }
6988 
6989     if (req->flags & ASSOC_REQ_DISABLE_EHT)
6990         conn_flags |= IEEE80211_CONN_DISABLE_EHT;
6991 
6992     memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa));
6993     memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask,
6994            sizeof(ifmgd->ht_capa_mask));
6995 
6996     memcpy(&ifmgd->vht_capa, &req->vht_capa, sizeof(ifmgd->vht_capa));
6997     memcpy(&ifmgd->vht_capa_mask, &req->vht_capa_mask,
6998            sizeof(ifmgd->vht_capa_mask));
6999 
7000     memcpy(&ifmgd->s1g_capa, &req->s1g_capa, sizeof(ifmgd->s1g_capa));
7001     memcpy(&ifmgd->s1g_capa_mask, &req->s1g_capa_mask,
7002            sizeof(ifmgd->s1g_capa_mask));
7003 
7004     if (req->ie && req->ie_len) {
7005         memcpy(assoc_data->ie, req->ie, req->ie_len);
7006         assoc_data->ie_len = req->ie_len;
7007         assoc_data->ie_pos = assoc_data->ie + assoc_data->ie_len;
7008     } else {
7009         assoc_data->ie_pos = assoc_data->ie;
7010     }
7011 
7012     if (req->fils_kek) {
7013         /* should already be checked in cfg80211 - so warn */
7014         if (WARN_ON(req->fils_kek_len > FILS_MAX_KEK_LEN)) {
7015             err = -EINVAL;
7016             goto err_free;
7017         }
7018         memcpy(assoc_data->fils_kek, req->fils_kek,
7019                req->fils_kek_len);
7020         assoc_data->fils_kek_len = req->fils_kek_len;
7021     }
7022 
7023     if (req->fils_nonces)
7024         memcpy(assoc_data->fils_nonces, req->fils_nonces,
7025                2 * FILS_NONCE_LEN);
7026 
7027     /* default timeout */
7028     assoc_data->timeout = jiffies;
7029     assoc_data->timeout_started = true;
7030 
7031     assoc_data->assoc_link_id = assoc_link_id;
7032 
7033     if (req->ap_mld_addr) {
7034         for (i = 0; i < ARRAY_SIZE(assoc_data->link); i++) {
7035             assoc_data->link[i].conn_flags = conn_flags;
7036             assoc_data->link[i].bss = req->links[i].bss;
7037         }
7038 
7039         /* if there was no authentication, set up the link */
7040         err = ieee80211_vif_set_links(sdata, BIT(assoc_link_id));
7041         if (err)
7042             goto err_clear;
7043     } else {
7044         assoc_data->link[0].conn_flags = conn_flags;
7045         assoc_data->link[0].bss = cbss;
7046     }
7047 
7048     link = sdata_dereference(sdata->link[assoc_link_id], sdata);
7049     if (WARN_ON(!link)) {
7050         err = -EINVAL;
7051         goto err_clear;
7052     }
7053 
7054     /* keep old conn_flags from ieee80211_prep_channel() from auth */
7055     conn_flags |= link->u.mgd.conn_flags;
7056     conn_flags |= ieee80211_setup_assoc_link(sdata, assoc_data, req,
7057                          conn_flags, assoc_link_id);
7058     override = link->u.mgd.conn_flags != conn_flags;
7059     link->u.mgd.conn_flags |= conn_flags;
7060 
7061     if (WARN((sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_UAPSD) &&
7062          ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK),
7063          "U-APSD not supported with HW_PS_NULLFUNC_STACK\n"))
7064         sdata->vif.driver_flags &= ~IEEE80211_VIF_SUPPORTS_UAPSD;
7065 
7066     if (bss->wmm_used && bss->uapsd_supported &&
7067         (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_UAPSD)) {
7068         assoc_data->uapsd = true;
7069         ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED;
7070     } else {
7071         assoc_data->uapsd = false;
7072         ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED;
7073     }
7074 
7075     if (req->prev_bssid)
7076         memcpy(assoc_data->prev_ap_addr, req->prev_bssid, ETH_ALEN);
7077 
7078     if (req->use_mfp) {
7079         ifmgd->mfp = IEEE80211_MFP_REQUIRED;
7080         ifmgd->flags |= IEEE80211_STA_MFP_ENABLED;
7081     } else {
7082         ifmgd->mfp = IEEE80211_MFP_DISABLED;
7083         ifmgd->flags &= ~IEEE80211_STA_MFP_ENABLED;
7084     }
7085 
7086     if (req->flags & ASSOC_REQ_USE_RRM)
7087         ifmgd->flags |= IEEE80211_STA_ENABLE_RRM;
7088     else
7089         ifmgd->flags &= ~IEEE80211_STA_ENABLE_RRM;
7090 
7091     if (req->crypto.control_port)
7092         ifmgd->flags |= IEEE80211_STA_CONTROL_PORT;
7093     else
7094         ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT;
7095 
7096     sdata->control_port_protocol = req->crypto.control_port_ethertype;
7097     sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
7098     sdata->control_port_over_nl80211 =
7099                     req->crypto.control_port_over_nl80211;
7100     sdata->control_port_no_preauth = req->crypto.control_port_no_preauth;
7101 
7102     /* kick off associate process */
7103     ifmgd->assoc_data = assoc_data;
7104 
7105     for (i = 0; i < ARRAY_SIZE(assoc_data->link); i++) {
7106         if (!assoc_data->link[i].bss)
7107             continue;
7108         if (i == assoc_data->assoc_link_id)
7109             continue;
7110         /* only calculate the flags, hence link == NULL */
7111         err = ieee80211_prep_channel(sdata, NULL, assoc_data->link[i].bss,
7112                          &assoc_data->link[i].conn_flags);
7113         if (err)
7114             goto err_clear;
7115     }
7116 
7117     /* needed for transmitting the assoc frames properly */
7118     memcpy(sdata->vif.cfg.ap_addr, assoc_data->ap_addr, ETH_ALEN);
7119 
7120     err = ieee80211_prep_connection(sdata, cbss, req->link_id,
7121                     req->ap_mld_addr, true, override);
7122     if (err)
7123         goto err_clear;
7124 
7125     assoc_data->link[assoc_data->assoc_link_id].conn_flags =
7126         link->u.mgd.conn_flags;
7127 
7128     if (ieee80211_hw_check(&sdata->local->hw, NEED_DTIM_BEFORE_ASSOC)) {
7129         const struct cfg80211_bss_ies *beacon_ies;
7130 
7131         rcu_read_lock();
7132         beacon_ies = rcu_dereference(req->bss->beacon_ies);
7133 
7134         if (beacon_ies) {
7135             /*
7136              * Wait up to one beacon interval ...
7137              * should this be more if we miss one?
7138              */
7139             sdata_info(sdata, "waiting for beacon from %pM\n",
7140                    link->u.mgd.bssid);
7141             assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval);
7142             assoc_data->timeout_started = true;
7143             assoc_data->need_beacon = true;
7144         }
7145         rcu_read_unlock();
7146     }
7147 
7148     run_again(sdata, assoc_data->timeout);
7149 
7150     return 0;
7151  err_clear:
7152     eth_zero_addr(sdata->deflink.u.mgd.bssid);
7153     ieee80211_link_info_change_notify(sdata, &sdata->deflink,
7154                       BSS_CHANGED_BSSID);
7155     ifmgd->assoc_data = NULL;
7156  err_free:
7157     kfree(assoc_data);
7158     return err;
7159 }
7160 
7161 int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
7162              struct cfg80211_deauth_request *req)
7163 {
7164     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
7165     u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
7166     bool tx = !req->local_state_change;
7167     struct ieee80211_prep_tx_info info = {
7168         .subtype = IEEE80211_STYPE_DEAUTH,
7169     };
7170 
7171     if (ifmgd->auth_data &&
7172         ether_addr_equal(ifmgd->auth_data->ap_addr, req->bssid)) {
7173         sdata_info(sdata,
7174                "aborting authentication with %pM by local choice (Reason: %u=%s)\n",
7175                req->bssid, req->reason_code,
7176                ieee80211_get_reason_code_string(req->reason_code));
7177 
7178         drv_mgd_prepare_tx(sdata->local, sdata, &info);
7179         ieee80211_send_deauth_disassoc(sdata, req->bssid, req->bssid,
7180                            IEEE80211_STYPE_DEAUTH,
7181                            req->reason_code, tx,
7182                            frame_buf);
7183         ieee80211_destroy_auth_data(sdata, false);
7184         ieee80211_report_disconnect(sdata, frame_buf,
7185                         sizeof(frame_buf), true,
7186                         req->reason_code, false);
7187         drv_mgd_complete_tx(sdata->local, sdata, &info);
7188         return 0;
7189     }
7190 
7191     if (ifmgd->assoc_data &&
7192         ether_addr_equal(ifmgd->assoc_data->ap_addr, req->bssid)) {
7193         sdata_info(sdata,
7194                "aborting association with %pM by local choice (Reason: %u=%s)\n",
7195                req->bssid, req->reason_code,
7196                ieee80211_get_reason_code_string(req->reason_code));
7197 
7198         drv_mgd_prepare_tx(sdata->local, sdata, &info);
7199         ieee80211_send_deauth_disassoc(sdata, req->bssid, req->bssid,
7200                            IEEE80211_STYPE_DEAUTH,
7201                            req->reason_code, tx,
7202                            frame_buf);
7203         ieee80211_destroy_assoc_data(sdata, ASSOC_ABANDON);
7204         ieee80211_report_disconnect(sdata, frame_buf,
7205                         sizeof(frame_buf), true,
7206                         req->reason_code, false);
7207         return 0;
7208     }
7209 
7210     if (ifmgd->associated &&
7211         ether_addr_equal(sdata->vif.cfg.ap_addr, req->bssid)) {
7212         sdata_info(sdata,
7213                "deauthenticating from %pM by local choice (Reason: %u=%s)\n",
7214                req->bssid, req->reason_code,
7215                ieee80211_get_reason_code_string(req->reason_code));
7216 
7217         ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
7218                        req->reason_code, tx, frame_buf);
7219         ieee80211_report_disconnect(sdata, frame_buf,
7220                         sizeof(frame_buf), true,
7221                         req->reason_code, false);
7222         drv_mgd_complete_tx(sdata->local, sdata, &info);
7223         return 0;
7224     }
7225 
7226     return -ENOTCONN;
7227 }
7228 
7229 int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
7230                struct cfg80211_disassoc_request *req)
7231 {
7232     u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
7233 
7234     if (!sdata->u.mgd.associated ||
7235         memcmp(sdata->vif.cfg.ap_addr, req->ap_addr, ETH_ALEN))
7236         return -ENOTCONN;
7237 
7238     sdata_info(sdata,
7239            "disassociating from %pM by local choice (Reason: %u=%s)\n",
7240            req->ap_addr, req->reason_code,
7241            ieee80211_get_reason_code_string(req->reason_code));
7242 
7243     ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC,
7244                    req->reason_code, !req->local_state_change,
7245                    frame_buf);
7246 
7247     ieee80211_report_disconnect(sdata, frame_buf, sizeof(frame_buf), true,
7248                     req->reason_code, false);
7249 
7250     return 0;
7251 }
7252 
7253 void ieee80211_mgd_stop_link(struct ieee80211_link_data *link)
7254 {
7255     cancel_work_sync(&link->u.mgd.request_smps_work);
7256     cancel_work_sync(&link->u.mgd.chswitch_work);
7257 }
7258 
7259 void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
7260 {
7261     struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
7262 
7263     /*
7264      * Make sure some work items will not run after this,
7265      * they will not do anything but might not have been
7266      * cancelled when disconnecting.
7267      */
7268     cancel_work_sync(&ifmgd->monitor_work);
7269     cancel_work_sync(&ifmgd->beacon_connection_loss_work);
7270     cancel_work_sync(&ifmgd->csa_connection_drop_work);
7271     cancel_delayed_work_sync(&ifmgd->tdls_peer_del_work);
7272 
7273     sdata_lock(sdata);
7274     if (ifmgd->assoc_data)
7275         ieee80211_destroy_assoc_data(sdata, ASSOC_TIMEOUT);
7276     if (ifmgd->auth_data)
7277         ieee80211_destroy_auth_data(sdata, false);
7278     spin_lock_bh(&ifmgd->teardown_lock);
7279     if (ifmgd->teardown_skb) {
7280         kfree_skb(ifmgd->teardown_skb);
7281         ifmgd->teardown_skb = NULL;
7282         ifmgd->orig_teardown_skb = NULL;
7283     }
7284     kfree(ifmgd->assoc_req_ies);
7285     ifmgd->assoc_req_ies = NULL;
7286     ifmgd->assoc_req_ies_len = 0;
7287     spin_unlock_bh(&ifmgd->teardown_lock);
7288     del_timer_sync(&ifmgd->timer);
7289     sdata_unlock(sdata);
7290 }
7291 
7292 void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
7293                    enum nl80211_cqm_rssi_threshold_event rssi_event,
7294                    s32 rssi_level,
7295                    gfp_t gfp)
7296 {
7297     struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
7298 
7299     trace_api_cqm_rssi_notify(sdata, rssi_event, rssi_level);
7300 
7301     cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, rssi_level, gfp);
7302 }
7303 EXPORT_SYMBOL(ieee80211_cqm_rssi_notify);
7304 
7305 void ieee80211_cqm_beacon_loss_notify(struct ieee80211_vif *vif, gfp_t gfp)
7306 {
7307     struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
7308 
7309     trace_api_cqm_beacon_loss_notify(sdata->local, sdata);
7310 
7311     cfg80211_cqm_beacon_loss_notify(sdata->dev, gfp);
7312 }
7313 EXPORT_SYMBOL(ieee80211_cqm_beacon_loss_notify);
7314 
7315 static void _ieee80211_enable_rssi_reports(struct ieee80211_sub_if_data *sdata,
7316                         int rssi_min_thold,
7317                         int rssi_max_thold)
7318 {
7319     trace_api_enable_rssi_reports(sdata, rssi_min_thold, rssi_max_thold);
7320 
7321     if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
7322         return;
7323 
7324     /*
7325      * Scale up threshold values before storing it, as the RSSI averaging
7326      * algorithm uses a scaled up value as well. Change this scaling
7327      * factor if the RSSI averaging algorithm changes.
7328      */
7329     sdata->u.mgd.rssi_min_thold = rssi_min_thold*16;
7330     sdata->u.mgd.rssi_max_thold = rssi_max_thold*16;
7331 }
7332 
7333 void ieee80211_enable_rssi_reports(struct ieee80211_vif *vif,
7334                     int rssi_min_thold,
7335                     int rssi_max_thold)
7336 {
7337     struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
7338 
7339     WARN_ON(rssi_min_thold == rssi_max_thold ||
7340         rssi_min_thold > rssi_max_thold);
7341 
7342     _ieee80211_enable_rssi_reports(sdata, rssi_min_thold,
7343                        rssi_max_thold);
7344 }
7345 EXPORT_SYMBOL(ieee80211_enable_rssi_reports);
7346 
7347 void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif)
7348 {
7349     struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
7350 
7351     _ieee80211_enable_rssi_reports(sdata, 0, 0);
7352 }
7353 EXPORT_SYMBOL(ieee80211_disable_rssi_reports);