Merge tag 'fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm...
[firefly-linux-kernel-4.4.55.git] / net / mac80211 / scan.c
index 88c81616f8f758595e90cced1d503448ce6ba969..f40661eb75b578dd2e409757331c085d36461723 100644 (file)
@@ -309,7 +309,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
        if (local->scan_req != local->int_scan_req)
                cfg80211_scan_done(local->scan_req, aborted);
        local->scan_req = NULL;
-       rcu_assign_pointer(local->scan_sdata, NULL);
+       RCU_INIT_POINTER(local->scan_sdata, NULL);
 
        local->scanning = 0;
        local->scan_chandef.chan = NULL;
@@ -472,9 +472,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
        if (local->ops->hw_scan) {
                u8 *ies;
 
-               local->hw_scan_ies_bufsize = 2 + IEEE80211_MAX_SSID_LEN +
-                                            local->scan_ies_len +
-                                            req->ie_len;
+               local->hw_scan_ies_bufsize = local->scan_ies_len + req->ie_len;
                local->hw_scan_req = kmalloc(
                                sizeof(*local->hw_scan_req) +
                                req->n_channels * sizeof(req->channels[0]) +
@@ -561,7 +559,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
                ieee80211_recalc_idle(local);
 
                local->scan_req = NULL;
-               rcu_assign_pointer(local->scan_sdata, NULL);
+               RCU_INIT_POINTER(local->scan_sdata, NULL);
        }
 
        return rc;
@@ -775,7 +773,7 @@ void ieee80211_scan_work(struct work_struct *work)
                int rc;
 
                local->scan_req = NULL;
-               rcu_assign_pointer(local->scan_sdata, NULL);
+               RCU_INIT_POINTER(local->scan_sdata, NULL);
 
                rc = __ieee80211_start_scan(sdata, req);
                if (rc) {
@@ -979,8 +977,7 @@ int __ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata,
        struct cfg80211_chan_def chandef;
        int ret, i, iebufsz;
 
-       iebufsz = 2 + IEEE80211_MAX_SSID_LEN +
-                 local->scan_ies_len + req->ie_len;
+       iebufsz = local->scan_ies_len + req->ie_len;
 
        lockdep_assert_held(&local->mtx);
 
@@ -1017,7 +1014,7 @@ out_free:
 
        if (ret) {
                /* Clean in case of failure after HW restart or upon resume. */
-               rcu_assign_pointer(local->sched_scan_sdata, NULL);
+               RCU_INIT_POINTER(local->sched_scan_sdata, NULL);
                local->sched_scan_req = NULL;
        }
 
@@ -1058,9 +1055,11 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
        /* We don't want to restart sched scan anymore. */
        local->sched_scan_req = NULL;
 
-       if (rcu_access_pointer(local->sched_scan_sdata))
-               drv_sched_scan_stop(local, sdata);
-
+       if (rcu_access_pointer(local->sched_scan_sdata)) {
+               ret = drv_sched_scan_stop(local, sdata);
+               if (!ret)
+                       rcu_assign_pointer(local->sched_scan_sdata, NULL);
+       }
 out:
        mutex_unlock(&local->mtx);
 
@@ -1077,12 +1076,8 @@ void ieee80211_sched_scan_results(struct ieee80211_hw *hw)
 }
 EXPORT_SYMBOL(ieee80211_sched_scan_results);
 
-void ieee80211_sched_scan_stopped_work(struct work_struct *work)
+void ieee80211_sched_scan_end(struct ieee80211_local *local)
 {
-       struct ieee80211_local *local =
-               container_of(work, struct ieee80211_local,
-                            sched_scan_stopped_work);
-
        mutex_lock(&local->mtx);
 
        if (!rcu_access_pointer(local->sched_scan_sdata)) {
@@ -1090,7 +1085,7 @@ void ieee80211_sched_scan_stopped_work(struct work_struct *work)
                return;
        }
 
-       rcu_assign_pointer(local->sched_scan_sdata, NULL);
+       RCU_INIT_POINTER(local->sched_scan_sdata, NULL);
 
        /* If sched scan was aborted by the driver. */
        local->sched_scan_req = NULL;
@@ -1100,6 +1095,15 @@ void ieee80211_sched_scan_stopped_work(struct work_struct *work)
        cfg80211_sched_scan_stopped(local->hw.wiphy);
 }
 
+void ieee80211_sched_scan_stopped_work(struct work_struct *work)
+{
+       struct ieee80211_local *local =
+               container_of(work, struct ieee80211_local,
+                            sched_scan_stopped_work);
+
+       ieee80211_sched_scan_end(local);
+}
+
 void ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
 {
        struct ieee80211_local *local = hw_to_local(hw);