Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
[firefly-linux-kernel-4.4.55.git] / net / mac80211 / mlme.c
index b3a3ce316656ce8406859a3cdc325fa262e024a5..900ead344f5bd526fa5f9a54b438a8cae52012e6 100644 (file)
@@ -330,6 +330,16 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
        if (WARN_ON_ONCE(!sta))
                return -EINVAL;
 
+       /*
+        * if bss configuration changed store the new one -
+        * this may be applicable even if channel is identical
+        */
+       ht_opmode = le16_to_cpu(ht_oper->operation_mode);
+       if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
+               *changed |= BSS_CHANGED_HT;
+               sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
+       }
+
        chan = sdata->vif.bss_conf.chandef.chan;
        sband = local->hw.wiphy->bands[chan->band];
 
@@ -416,14 +426,6 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
                                         IEEE80211_RC_BW_CHANGED);
        }
 
-       ht_opmode = le16_to_cpu(ht_oper->operation_mode);
-
-       /* if bss configuration changed store the new one */
-       if (sdata->vif.bss_conf.ht_operation_mode != ht_opmode) {
-               *changed |= BSS_CHANGED_HT;
-               sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
-       }
-
        return 0;
 }
 
@@ -714,7 +716,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
        }
 
        /* if present, add any custom IEs that go before HT */
-       if (assoc_data->ie_len && assoc_data->ie) {
+       if (assoc_data->ie_len) {
                static const u8 before_ht[] = {
                        WLAN_EID_SSID,
                        WLAN_EID_SUPP_RATES,
@@ -748,7 +750,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
                                     &assoc_data->ap_vht_cap);
 
        /* if present, add any custom non-vendor IEs that go after HT */
-       if (assoc_data->ie_len && assoc_data->ie) {
+       if (assoc_data->ie_len) {
                noffset = ieee80211_ie_split_vendor(assoc_data->ie,
                                                    assoc_data->ie_len,
                                                    offset);
@@ -779,7 +781,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
        }
 
        /* add any remaining custom (i.e. vendor specific here) IEs */
-       if (assoc_data->ie_len && assoc_data->ie) {
+       if (assoc_data->ie_len) {
                noffset = assoc_data->ie_len;
                pos = skb_put(skb, noffset - offset);
                memcpy(pos, assoc_data->ie + offset, noffset - offset);
@@ -886,8 +888,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
        if (!ifmgd->associated)
                goto out;
 
-       ret = ieee80211_vif_change_channel(sdata, &local->csa_chandef,
-                                          &changed);
+       ret = ieee80211_vif_change_channel(sdata, &changed);
        if (ret) {
                sdata_info(sdata,
                           "vif channel switch failed, disconnecting\n");
@@ -897,7 +898,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
        }
 
        if (!local->use_chanctx) {
-               local->_oper_chandef = local->csa_chandef;
+               local->_oper_chandef = sdata->csa_chandef;
                /* Call "hw_config" only if doing sw channel switch.
                 * Otherwise update the channel directly
                 */
@@ -908,7 +909,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
        }
 
        /* XXX: shouldn't really modify cfg80211-owned data! */
-       ifmgd->associated->channel = local->csa_chandef.chan;
+       ifmgd->associated->channel = sdata->csa_chandef.chan;
 
        /* XXX: wait for a beacon first? */
        ieee80211_wake_queues_by_reason(&local->hw,
@@ -1035,7 +1036,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
        }
        mutex_unlock(&local->chanctx_mtx);
 
-       local->csa_chandef = csa_ie.chandef;
+       sdata->csa_chandef = csa_ie.chandef;
 
        if (csa_ie.mode)
                ieee80211_stop_queues_by_reason(&local->hw,
@@ -1398,10 +1399,12 @@ void ieee80211_dfs_cac_timer_work(struct work_struct *work)
        struct ieee80211_sub_if_data *sdata =
                container_of(delayed_work, struct ieee80211_sub_if_data,
                             dfs_cac_timer_work);
+       struct cfg80211_chan_def chandef = sdata->vif.bss_conf.chandef;
 
        ieee80211_vif_release_channel(sdata);
-
-       cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_FINISHED, GFP_KERNEL);
+       cfg80211_cac_event(sdata->dev, &chandef,
+                          NL80211_RADAR_CAC_FINISHED,
+                          GFP_KERNEL);
 }
 
 /* MLME */
@@ -1745,6 +1748,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
 
        ifmgd->flags = 0;
        ieee80211_vif_release_channel(sdata);
+
+       sdata->encrypt_headroom = IEEE80211_ENCRYPT_HEADROOM;
 }
 
 void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
@@ -4191,6 +4196,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
 
        sdata->control_port_protocol = req->crypto.control_port_ethertype;
        sdata->control_port_no_encrypt = req->crypto.control_port_no_encrypt;
+       sdata->encrypt_headroom = ieee80211_cs_headroom(local, &req->crypto,
+                                                       sdata->vif.type);
 
        /* kick off associate process */