]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
authorJohn W. Linville <linville@tuxdriver.com>
Tue, 27 May 2014 17:47:27 +0000 (13:47 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 27 May 2014 17:47:27 +0000 (13:47 -0400)
1  2 
include/uapi/linux/nl80211.h
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c

index fb0efa1f90660e3260da4df31cbbc10fc6f853ec,194c1eab04d8ad9cb37ae855d8c011d48722c829..be9519b52bb10edef5e5be12ddd3ff2065d706ac
   *    TX status event pertaining to the TX request.
   *    %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the
   *    management frames at CCK rate or not in 2GHz band.
 + *    %NL80211_ATTR_CSA_C_OFFSETS_TX is an array of offsets to CSA
 + *    counters which will be updated to the current value. This attribute
 + *    is used during CSA period.
   * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this
   *    command may be used with the corresponding cookie to cancel the wait
   *    time if it is known that it is no longer necessary.
@@@ -1528,10 -1525,10 +1528,10 @@@ enum nl80211_commands 
   *    operation).
   * @NL80211_ATTR_CSA_IES: Nested set of attributes containing the IE information
   *    for the time while performing a channel switch.
 - * @NL80211_ATTR_CSA_C_OFF_BEACON: Offset of the channel switch counter
 - *    field in the beacons tail (%NL80211_ATTR_BEACON_TAIL).
 - * @NL80211_ATTR_CSA_C_OFF_PRESP: Offset of the channel switch counter
 - *    field in the probe response (%NL80211_ATTR_PROBE_RESP).
 + * @NL80211_ATTR_CSA_C_OFF_BEACON: An array of offsets (u16) to the channel
 + *    switch counters in the beacons tail (%NL80211_ATTR_BEACON_TAIL).
 + * @NL80211_ATTR_CSA_C_OFF_PRESP: An array of offsets (u16) to the channel
 + *    switch counters in the probe response (%NL80211_ATTR_PROBE_RESP).
   *
   * @NL80211_ATTR_RXMGMT_FLAGS: flags for nl80211_send_mgmt(), u32.
   *    As specified in the &enum nl80211_rxmgmt_flags.
   *    advertise values that cannot always be met. In such cases, an attempt
   *    to add a new station entry with @NL80211_CMD_NEW_STATION may fail.
   *
 + * @NL80211_ATTR_CSA_C_OFFSETS_TX: An array of csa counter offsets (u16) which
 + *    should be updated when the frame is transmitted.
 + * @NL80211_ATTR_MAX_CSA_COUNTERS: U8 attribute used to advertise the maximum
 + *    supported number of csa counters.
 + *
   * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32.
   *    As specified in the &enum nl80211_tdls_peer_capability.
   *
 + * @NL80211_ATTR_IFACE_SOCKET_OWNER: flag attribute, if set during interface
 + *    creation then the new interface will be owned by the netlink socket
 + *    that created it and will be destroyed when the socket is closed
 + *
   * @NL80211_ATTR_MAX: highest attribute number currently defined
   * @__NL80211_ATTR_AFTER_LAST: internal use
   */
@@@ -1926,11 -1914,6 +1926,11 @@@ enum nl80211_attrs 
  
        NL80211_ATTR_TDLS_PEER_CAPABILITY,
  
 +      NL80211_ATTR_IFACE_SOCKET_OWNER,
 +
 +      NL80211_ATTR_CSA_C_OFFSETS_TX,
 +      NL80211_ATTR_MAX_CSA_COUNTERS,
 +
        /* add attributes here, update the policy in nl80211.c */
  
        __NL80211_ATTR_AFTER_LAST,
@@@ -2199,8 -2182,6 +2199,8 @@@ enum nl80211_sta_bss_param 
   *    Contains a nested array of signal strength attributes (u8, dBm)
   * @NL80211_STA_INFO_CHAIN_SIGNAL_AVG: per-chain signal strength average
   *    Same format as NL80211_STA_INFO_CHAIN_SIGNAL.
 + * @NL80211_STA_EXPECTED_THROUGHPUT: expected throughput considering also the
 + *    802.11 header (u32, kbps)
   * @__NL80211_STA_INFO_AFTER_LAST: internal
   * @NL80211_STA_INFO_MAX: highest possible station info attribute
   */
@@@ -2232,7 -2213,6 +2232,7 @@@ enum nl80211_sta_info 
        NL80211_STA_INFO_TX_BYTES64,
        NL80211_STA_INFO_CHAIN_SIGNAL,
        NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
 +      NL80211_STA_INFO_EXPECTED_THROUGHPUT,
  
        /* keep last */
        __NL80211_STA_INFO_AFTER_LAST,
@@@ -2356,34 -2336,9 +2356,34 @@@ enum nl80211_band_attr 
   *    using this channel as the primary or any of the secondary channels
   *    isn't possible
   * @NL80211_FREQUENCY_ATTR_DFS_CAC_TIME: DFS CAC time in milliseconds.
 + * @NL80211_FREQUENCY_ATTR_INDOOR_ONLY: Only indoor use is permitted on this
 + *    channel. A channel that has the INDOOR_ONLY attribute can only be
 + *    used when there is a clear assessment that the device is operating in
 + *    an indoor surroundings, i.e., it is connected to AC power (and not
 + *    through portable DC inverters) or is under the control of a master
 + *    that is acting as an AP and is connected to AC power.
 + * @NL80211_FREQUENCY_ATTR_GO_CONCURRENT: GO operation is allowed on this
 + *    channel if it's connected concurrently to a BSS on the same channel on
 + *    the 2 GHz band or to a channel in the same UNII band (on the 5 GHz
 + *    band), and IEEE80211_CHAN_RADAR is not set. Instantiating a GO on a
 + *    channel that has the GO_CONCURRENT attribute set can be done when there
 + *    is a clear assessment that the device is operating under the guidance of
 + *    an authorized master, i.e., setting up a GO while the device is also
 + *    connected to an AP with DFS and radar detection on the UNII band (it is
 + *    up to user-space, i.e., wpa_supplicant to perform the required
 + *    verifications)
 + * @NL80211_FREQUENCY_ATTR_NO_20MHZ: 20 MHz operation is not allowed
 + *    on this channel in current regulatory domain.
 + * @NL80211_FREQUENCY_ATTR_NO_10MHZ: 10 MHz operation is not allowed
 + *    on this channel in current regulatory domain.
   * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
   *    currently defined
   * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
 + *
 + * See https://apps.fcc.gov/eas/comments/GetPublishedDocument.html?id=327&tn=528122
 + * for more information on the FCC description of the relaxations allowed
 + * by NL80211_FREQUENCY_ATTR_INDOOR_ONLY and
 + * NL80211_FREQUENCY_ATTR_GO_CONCURRENT.
   */
  enum nl80211_frequency_attr {
        __NL80211_FREQUENCY_ATTR_INVALID,
        NL80211_FREQUENCY_ATTR_NO_80MHZ,
        NL80211_FREQUENCY_ATTR_NO_160MHZ,
        NL80211_FREQUENCY_ATTR_DFS_CAC_TIME,
 +      NL80211_FREQUENCY_ATTR_INDOOR_ONLY,
 +      NL80211_FREQUENCY_ATTR_GO_CONCURRENT,
 +      NL80211_FREQUENCY_ATTR_NO_20MHZ,
 +      NL80211_FREQUENCY_ATTR_NO_10MHZ,
  
        /* keep last */
        __NL80211_FREQUENCY_ATTR_AFTER_LAST,
@@@ -2622,13 -2573,10 +2622,13 @@@ enum nl80211_dfs_regions 
   *    present has been registered with the wireless core that
   *    has listed NL80211_FEATURE_CELL_BASE_REG_HINTS as a
   *    supported feature.
 + * @NL80211_USER_REG_HINT_INDOOR: a user sent an hint indicating that the
 + *    platform is operating in an indoor environment.
   */
  enum nl80211_user_reg_hint_type {
        NL80211_USER_REG_HINT_USER      = 0,
        NL80211_USER_REG_HINT_CELL_BASE = 1,
 +      NL80211_USER_REG_HINT_INDOOR    = 2,
  };
  
  /**
@@@ -3702,8 -3650,6 +3702,8 @@@ enum nl80211_iface_limit_attrs 
   *    different channels may be used within this group.
   * @NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS: u32 attribute containing the bitmap
   *    of supported channel widths for radar detection.
 + * @NL80211_IFACE_COMB_RADAR_DETECT_REGIONS: u32 attribute containing the bitmap
 + *    of supported regulatory regions for radar detection.
   * @NUM_NL80211_IFACE_COMB: number of attributes
   * @MAX_NL80211_IFACE_COMB: highest attribute number
   *
@@@ -3737,7 -3683,6 +3737,7 @@@ enum nl80211_if_combination_attrs 
        NL80211_IFACE_COMB_STA_AP_BI_MATCH,
        NL80211_IFACE_COMB_NUM_CHANNELS,
        NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS,
 +      NL80211_IFACE_COMB_RADAR_DETECT_REGIONS,
  
        /* keep last */
        NUM_NL80211_IFACE_COMB,
@@@ -3911,6 -3856,8 +3911,8 @@@ enum nl80211_ap_sme_features 
   * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested
   *    to work properly to suppport receiving regulatory hints from
   *    cellular base stations.
+  * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: (no longer available, only
+  *    here to reserve the value for API/ABI compatibility)
   * @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of
   *    equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station
   *    mode
   *    interface. An active monitor interface behaves like a normal monitor
   *    interface, but gets added to the driver. It ensures that incoming
   *    unicast packets directed at the configured interface address get ACKed.
 + * @NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE: This driver supports dynamic
 + *    channel bandwidth change (e.g., HT 20 <-> 40 MHz channel) during the
 + *    lifetime of a BSS.
   */
  enum nl80211_feature_flags {
        NL80211_FEATURE_SK_TX_STATUS                    = 1 << 0,
        NL80211_FEATURE_HT_IBSS                         = 1 << 1,
        NL80211_FEATURE_INACTIVITY_TIMER                = 1 << 2,
        NL80211_FEATURE_CELL_BASE_REG_HINTS             = 1 << 3,
-       /* bit 4 is reserved - don't use */
+       NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL        = 1 << 4,
        NL80211_FEATURE_SAE                             = 1 << 5,
        NL80211_FEATURE_LOW_PRIORITY_SCAN               = 1 << 6,
        NL80211_FEATURE_SCAN_FLUSH                      = 1 << 7,
        NL80211_FEATURE_FULL_AP_CLIENT_STATE            = 1 << 15,
        NL80211_FEATURE_USERSPACE_MPM                   = 1 << 16,
        NL80211_FEATURE_ACTIVE_MONITOR                  = 1 << 17,
 +      NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE       = 1 << 18,
  };
  
  /**
index ed2b817d5ece2cb9e31cb206a9813424f1637d5b,f169b6ee94ee8d6ee9c6daa5dc047c5f8b1d2740..ac9836e0aab335ddf75295b5ad020d77e0e3dd0a
@@@ -260,7 -260,7 +260,7 @@@ struct ieee80211_if_ap 
  
        /* to be used after channel switch. */
        struct cfg80211_beacon_data *next_beacon;
 -      struct list_head vlans;
 +      struct list_head vlans; /* write-protected with RTNL and local->mtx */
  
        struct ps_data ps;
        atomic_t num_mcast_sta; /* number of stations receiving multicast */
@@@ -276,7 -276,7 +276,7 @@@ struct ieee80211_if_wds 
  };
  
  struct ieee80211_if_vlan {
 -      struct list_head list;
 +      struct list_head list; /* write-protected with RTNL and local->mtx */
  
        /* used for all tx if the VLAN is configured to 4-addr mode */
        struct sta_info __rcu *sta;
@@@ -317,6 -317,7 +317,7 @@@ struct ieee80211_roc_work 
  
        bool started, abort, hw_begun, notified;
        bool to_be_freed;
+       bool on_channel;
  
        unsigned long hw_start_time;
  
@@@ -691,10 -692,8 +692,10 @@@ struct ieee80211_chanctx 
        struct list_head list;
        struct rcu_head rcu_head;
  
 +      struct list_head assigned_vifs;
 +      struct list_head reserved_vifs;
 +
        enum ieee80211_chanctx_mode mode;
 -      int refcount;
        bool driver_present;
  
        struct ieee80211_chanctx_conf conf;
@@@ -753,21 -752,11 +754,21 @@@ struct ieee80211_sub_if_data 
        struct mac80211_qos_map __rcu *qos_map;
  
        struct work_struct csa_finalize_work;
 -      int csa_counter_offset_beacon;
 -      int csa_counter_offset_presp;
 +      u16 csa_counter_offset_beacon[IEEE80211_MAX_CSA_COUNTERS_NUM];
 +      u16 csa_counter_offset_presp[IEEE80211_MAX_CSA_COUNTERS_NUM];
        bool csa_radar_required;
 +      bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */
        struct cfg80211_chan_def csa_chandef;
  
 +      struct list_head assigned_chanctx_list; /* protected by chanctx_mtx */
 +      struct list_head reserved_chanctx_list; /* protected by chanctx_mtx */
 +
 +      /* context reservation -- protected with chanctx_mtx */
 +      struct ieee80211_chanctx *reserved_chanctx;
 +      struct cfg80211_chan_def reserved_chandef;
 +      bool reserved_radar_required;
 +      u8 csa_current_counter;
 +
        /* used to reconfigure hardware SM PS */
        struct work_struct recalc_smps;
  
@@@ -1460,7 -1449,6 +1461,7 @@@ __ieee80211_request_sched_scan_start(st
  int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
                                       struct cfg80211_sched_scan_request *req);
  int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata);
 +void ieee80211_sched_scan_end(struct ieee80211_local *local);
  void ieee80211_sched_scan_stopped_work(struct work_struct *work);
  
  /* off-channel helpers */
@@@ -1475,7 -1463,6 +1476,7 @@@ void ieee80211_sw_roc_work(struct work_
  void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc);
  
  /* channel switch handling */
 +bool ieee80211_csa_needs_block_tx(struct ieee80211_local *local);
  void ieee80211_csa_finalize_work(struct work_struct *work);
  int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
                             struct cfg80211_csa_settings *params);
@@@ -1784,16 -1771,6 +1785,16 @@@ int __must_chec
  ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
                          const struct cfg80211_chan_def *chandef,
                          enum ieee80211_chanctx_mode mode);
 +int __must_check
 +ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata,
 +                            const struct cfg80211_chan_def *chandef,
 +                            enum ieee80211_chanctx_mode mode,
 +                            bool radar_required);
 +int __must_check
 +ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata,
 +                                 u32 *changed);
 +int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata);
 +
  int __must_check
  ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
                               const struct cfg80211_chan_def *chandef,
@@@ -1806,8 -1783,6 +1807,8 @@@ void ieee80211_vif_release_channel(stru
  void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata);
  void ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
                                         bool clear);
 +int ieee80211_chanctx_refcount(struct ieee80211_local *local,
 +                             struct ieee80211_chanctx *ctx);
  
  void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
                                   struct ieee80211_chanctx *chanctx);
@@@ -1831,20 -1806,6 +1832,20 @@@ int ieee80211_cs_headroom(struct ieee80
                          enum nl80211_iftype iftype);
  void ieee80211_recalc_dtim(struct ieee80211_local *local,
                           struct ieee80211_sub_if_data *sdata);
 +int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata,
 +                               const struct cfg80211_chan_def *chandef,
 +                               enum ieee80211_chanctx_mode chanmode,
 +                               u8 radar_detect);
 +int ieee80211_max_num_channels(struct ieee80211_local *local);
 +
 +/* TDLS */
 +int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
 +                      const u8 *peer, u8 action_code, u8 dialog_token,
 +                      u16 status_code, u32 peer_capability,
 +                      const u8 *extra_ies, size_t extra_ies_len);
 +int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev,
 +                      const u8 *peer, enum nl80211_tdls_operation oper);
 +
  
  #ifdef CONFIG_MAC80211_NOINLINE
  #define debug_noinline noinline
diff --combined net/mac80211/mlme.c
index 7f073ef1e0a675c3edbb92c049bbc05c02608276,27600a9808baeaa31be82ecb0f4218225b28665e..3345401be1b3c26744cb2ab6e384672a0cab0d6b
@@@ -975,23 -975,16 +975,23 @@@ static void ieee80211_chswitch_work(str
        /* XXX: shouldn't really modify cfg80211-owned data! */
        ifmgd->associated->channel = sdata->csa_chandef.chan;
  
 +      ieee80211_bss_info_change_notify(sdata, changed);
 +
 +      mutex_lock(&local->mtx);
 +      sdata->vif.csa_active = false;
        /* XXX: wait for a beacon first? */
 -      ieee80211_wake_queues_by_reason(&local->hw,
 +      if (!ieee80211_csa_needs_block_tx(local))
 +              ieee80211_wake_queues_by_reason(&local->hw,
                                        IEEE80211_MAX_QUEUE_MAP,
                                        IEEE80211_QUEUE_STOP_REASON_CSA);
 +      mutex_unlock(&local->mtx);
  
 -      ieee80211_bss_info_change_notify(sdata, changed);
 -
 - out:
 -      sdata->vif.csa_active = false;
        ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
 +
 +      ieee80211_sta_reset_beacon_monitor(sdata);
 +      ieee80211_sta_reset_conn_monitor(sdata);
 +
 +out:
        sdata_unlock(sdata);
  }
  
@@@ -1096,7 -1089,7 +1096,7 @@@ ieee80211_sta_process_chanswitch(struc
        }
        chanctx = container_of(rcu_access_pointer(sdata->vif.chanctx_conf),
                               struct ieee80211_chanctx, conf);
 -      if (chanctx->refcount > 1) {
 +      if (ieee80211_chanctx_refcount(local, chanctx) > 1) {
                sdata_info(sdata,
                           "channel switch with multiple interfaces on the same channel, disconnecting\n");
                ieee80211_queue_work(&local->hw,
        mutex_unlock(&local->chanctx_mtx);
  
        sdata->csa_chandef = csa_ie.chandef;
 +
 +      mutex_lock(&local->mtx);
        sdata->vif.csa_active = true;
 +      sdata->csa_block_tx = csa_ie.mode;
  
 -      if (csa_ie.mode)
 +      if (sdata->csa_block_tx)
                ieee80211_stop_queues_by_reason(&local->hw,
 -                              IEEE80211_MAX_QUEUE_MAP,
 -                              IEEE80211_QUEUE_STOP_REASON_CSA);
 +                                      IEEE80211_MAX_QUEUE_MAP,
 +                                      IEEE80211_QUEUE_STOP_REASON_CSA);
 +      mutex_unlock(&local->mtx);
  
        if (local->ops->channel_switch) {
                /* use driver's channel switch callback */
@@@ -1828,12 -1817,6 +1828,12 @@@ static void ieee80211_set_disassoc(stru
        ifmgd->flags = 0;
        mutex_lock(&local->mtx);
        ieee80211_vif_release_channel(sdata);
 +
 +      sdata->vif.csa_active = false;
 +      if (!ieee80211_csa_needs_block_tx(local))
 +              ieee80211_wake_queues_by_reason(&local->hw,
 +                                      IEEE80211_MAX_QUEUE_MAP,
 +                                      IEEE80211_QUEUE_STOP_REASON_CSA);
        mutex_unlock(&local->mtx);
  
        sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
@@@ -2062,7 -2045,6 +2062,7 @@@ EXPORT_SYMBOL(ieee80211_ap_probereq_get
  
  static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
  {
 +      struct ieee80211_local *local = sdata->local;
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
        u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
  
                               WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
                               true, frame_buf);
        ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
 +
 +      mutex_lock(&local->mtx);
        sdata->vif.csa_active = false;
 -      ieee80211_wake_queues_by_reason(&sdata->local->hw,
 +      if (!ieee80211_csa_needs_block_tx(local))
 +              ieee80211_wake_queues_by_reason(&local->hw,
                                        IEEE80211_MAX_QUEUE_MAP,
                                        IEEE80211_QUEUE_STOP_REASON_CSA);
 +      mutex_unlock(&local->mtx);
  
        cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
                              IEEE80211_DEAUTH_FRAME_LEN);
@@@ -3568,9 -3546,6 +3568,9 @@@ static void ieee80211_sta_bcn_mon_timer
        if (local->quiescing)
                return;
  
 +      if (sdata->vif.csa_active)
 +              return;
 +
        sdata->u.mgd.connection_loss = false;
        ieee80211_queue_work(&sdata->local->hw,
                             &sdata->u.mgd.beacon_connection_loss_work);
@@@ -3586,9 -3561,6 +3586,9 @@@ static void ieee80211_sta_conn_mon_time
        if (local->quiescing)
                return;
  
 +      if (sdata->vif.csa_active)
 +              return;
 +
        ieee80211_queue_work(&local->hw, &ifmgd->monitor_work);
  }
  
@@@ -3626,18 -3598,24 +3626,24 @@@ void ieee80211_mgd_quiesce(struct ieee8
  
        sdata_lock(sdata);
  
-       if (ifmgd->auth_data) {
+       if (ifmgd->auth_data || ifmgd->assoc_data) {
+               const u8 *bssid = ifmgd->auth_data ?
+                               ifmgd->auth_data->bss->bssid :
+                               ifmgd->assoc_data->bss->bssid;
                /*
-                * If we are trying to authenticate while suspending, cfg80211
-                * won't know and won't actually abort those attempts, thus we
-                * need to do that ourselves.
+                * If we are trying to authenticate / associate while suspending,
+                * cfg80211 won't know and won't actually abort those attempts,
+                * thus we need to do that ourselves.
                 */
-               ieee80211_send_deauth_disassoc(sdata,
-                                              ifmgd->auth_data->bss->bssid,
+               ieee80211_send_deauth_disassoc(sdata, bssid,
                                               IEEE80211_STYPE_DEAUTH,
                                               WLAN_REASON_DEAUTH_LEAVING,
                                               false, frame_buf);
-               ieee80211_destroy_auth_data(sdata, false);
+               if (ifmgd->assoc_data)
+                       ieee80211_destroy_assoc_data(sdata, false);
+               if (ifmgd->auth_data)
+                       ieee80211_destroy_auth_data(sdata, false);
                cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
                                      IEEE80211_DEAUTH_FRAME_LEN);
        }
@@@ -3729,7 -3707,7 +3735,7 @@@ int ieee80211_max_network_latency(struc
        ieee80211_recalc_ps(local, latency_usec);
        mutex_unlock(&local->iflist_mtx);
  
 -      return 0;
 +      return NOTIFY_OK;
  }
  
  static u8 ieee80211_ht_vht_rx_chains(struct ieee80211_sub_if_data *sdata,