Merge branch 'next/cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[firefly-linux-kernel-4.4.55.git] / net / mac80211 / mlme.c
index 4b0460ad8c8fc8744cd2b6884db819b4f738341f..d6470c7fd6ce34cd226632a30fac0e0be6c7f71f 100644 (file)
@@ -917,6 +917,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
                            params.aifs, params.cw_min, params.cw_max,
                            params.txop, params.uapsd);
 #endif
+               local->tx_conf[queue] = params;
                if (drv_conf_tx(local, queue, &params))
                        wiphy_debug(local->hw.wiphy,
                                    "failed to set TX queue parameters for queue %d\n",
@@ -1219,7 +1220,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
        } else {
                ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
                ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0,
-                                        true);
+                                        (u32) -1, true);
        }
 
        ifmgd->probe_send_count++;
@@ -1304,7 +1305,8 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
 
        ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID);
        skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid,
-                                       ssid + 2, ssid[1], NULL, 0, true);
+                                       (u32) -1, ssid + 2, ssid[1],
+                                       NULL, 0, true);
 
        return skb;
 }
@@ -2052,7 +2054,7 @@ static void ieee80211_sta_timer(unsigned long data)
 }
 
 static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
-                                         u8 *bssid)
+                                         u8 *bssid, u8 reason)
 {
        struct ieee80211_local *local = sdata->local;
        struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
@@ -2070,8 +2072,7 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
         * but that's not a problem.
         */
        ieee80211_send_deauth_disassoc(sdata, bssid,
-                       IEEE80211_STYPE_DEAUTH,
-                       WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
+                       IEEE80211_STYPE_DEAUTH, reason,
                        NULL, true);
        mutex_lock(&ifmgd->mtx);
 }
@@ -2117,7 +2118,8 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
                                            " AP %pM, disconnecting.\n",
                                            sdata->name, bssid);
 #endif
-                               ieee80211_sta_connection_lost(sdata, bssid);
+                               ieee80211_sta_connection_lost(sdata, bssid,
+                                       WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
                        }
                } else if (time_is_after_jiffies(ifmgd->probe_timeout))
                        run_again(ifmgd, ifmgd->probe_timeout);
@@ -2129,7 +2131,8 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
                                    sdata->name,
                                    bssid, probe_wait_ms);
 #endif
-                       ieee80211_sta_connection_lost(sdata, bssid);
+                       ieee80211_sta_connection_lost(sdata, bssid,
+                               WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
                } else if (ifmgd->probe_send_count < max_tries) {
 #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
                        wiphy_debug(local->hw.wiphy,
@@ -2151,7 +2154,8 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
                                    sdata->name,
                                    bssid, probe_wait_ms);
 
-                       ieee80211_sta_connection_lost(sdata, bssid);
+                       ieee80211_sta_connection_lost(sdata, bssid,
+                               WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY);
                }
        }
 
@@ -2241,6 +2245,24 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
        if (!ifmgd->associated)
                return;
 
+       if (sdata->flags & IEEE80211_SDATA_DISCONNECT_RESUME) {
+               sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME;
+               mutex_lock(&ifmgd->mtx);
+               if (ifmgd->associated) {
+#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+                       wiphy_debug(sdata->local->hw.wiphy,
+                                   "%s: driver requested disconnect after resume.\n",
+                                   sdata->name);
+#endif
+                       ieee80211_sta_connection_lost(sdata,
+                               ifmgd->associated->bssid,
+                               WLAN_REASON_UNSPECIFIED);
+                       mutex_unlock(&ifmgd->mtx);
+                       return;
+               }
+               mutex_unlock(&ifmgd->mtx);
+       }
+
        if (test_and_clear_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running))
                add_timer(&ifmgd->timer);
        if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))
@@ -2313,14 +2335,16 @@ static enum work_done_result
 ieee80211_probe_auth_done(struct ieee80211_work *wk,
                          struct sk_buff *skb)
 {
+       struct ieee80211_local *local = wk->sdata->local;
+
        if (!skb) {
                cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta);
-               return WORK_DONE_DESTROY;
+               goto destroy;
        }
 
        if (wk->type == IEEE80211_WORK_AUTH) {
                cfg80211_send_rx_auth(wk->sdata->dev, skb->data, skb->len);
-               return WORK_DONE_DESTROY;
+               goto destroy;
        }
 
        mutex_lock(&wk->sdata->u.mgd.mtx);
@@ -2330,6 +2354,12 @@ ieee80211_probe_auth_done(struct ieee80211_work *wk,
        wk->type = IEEE80211_WORK_AUTH;
        wk->probe_auth.tries = 0;
        return WORK_DONE_REQUEUE;
+ destroy:
+       if (wk->probe_auth.synced)
+               drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
+                                  IEEE80211_TX_SYNC_AUTH);
+
+       return WORK_DONE_DESTROY;
 }
 
 int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
@@ -2402,6 +2432,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
 static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
                                                  struct sk_buff *skb)
 {
+       struct ieee80211_local *local = wk->sdata->local;
        struct ieee80211_mgmt *mgmt;
        struct ieee80211_rx_status *rx_status;
        struct ieee802_11_elems elems;
@@ -2409,7 +2440,7 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
 
        if (!skb) {
                cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta);
-               return WORK_DONE_DESTROY;
+               goto destroy;
        }
 
        if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) {
@@ -2429,6 +2460,10 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
        status = le16_to_cpu(mgmt->u.assoc_resp.status_code);
 
        if (status == WLAN_STATUS_SUCCESS) {
+               if (wk->assoc.synced)
+                       drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
+                                          IEEE80211_TX_SYNC_ASSOC);
+
                mutex_lock(&wk->sdata->u.mgd.mtx);
                if (!ieee80211_assoc_success(wk, mgmt, skb->len)) {
                        mutex_unlock(&wk->sdata->u.mgd.mtx);
@@ -2442,6 +2477,11 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
        }
 
        cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len);
+ destroy:
+       if (wk->assoc.synced)
+               drv_finish_tx_sync(local, wk->sdata, wk->filter_ta,
+                                  IEEE80211_TX_SYNC_ASSOC);
+
        return WORK_DONE_DESTROY;
 }