struct ieee80211_sub_if_data *sdata,
                              unsigned int queues, bool drop);
 
+static inline bool ieee80211_can_run_worker(struct ieee80211_local *local)
+{
+       /*
+        * If quiescing is set, we are racing with __ieee80211_suspend.
+        * __ieee80211_suspend flushes the workers after setting quiescing,
+        * and we check quiescing / suspended before enqueing new workers.
+        * We should abort the worker to avoid the races below.
+        */
+       if (local->quiescing)
+               return false;
+
+       /*
+        * We might already be suspended if the following scenario occurs:
+        * __ieee80211_suspend          Control path
+        *
+        *                              if (local->quiescing)
+        *                                      return;
+        * local->quiescing = true;
+        * flush_workqueue();
+        *                              queue_work(...);
+        * local->suspended = true;
+        * local->quiescing = false;
+        *                              worker starts running...
+        */
+       if (local->suspended)
+               return false;
+
+       return true;
+}
+
 void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
                         u16 transaction, u16 auth_alg, u16 status,
                         const u8 *extra, size_t extra_len, const u8 *bssid,
 
        if (local->scanning)
                return;
 
-       /*
-        * ieee80211_queue_work() should have picked up most cases,
-        * here we'll pick the rest.
-        */
-       if (WARN(local->suspended,
-                "interface work scheduled while going to suspend\n"))
+       if (!ieee80211_can_run_worker(local))
                return;
 
        /* first process frames */
 
 
 /*
  * Nothing should have been stuffed into the workqueue during
- * the suspend->resume cycle. If this WARN is seen then there
- * is a bug with either the driver suspend or something in
- * mac80211 stuffing into the workqueue which we haven't yet
- * cleared during mac80211's suspend cycle.
+ * the suspend->resume cycle. Since we can't check each caller
+ * of this function if we are already quiescing / suspended,
+ * check here and don't WARN since this can actually happen when
+ * the rx path (for example) is racing against __ieee80211_suspend
+ * and suspending / quiescing was set after the rx path checked
+ * them.
  */
 static bool ieee80211_can_queue_work(struct ieee80211_local *local)
 {
-       if (WARN(local->suspended && !local->resuming,
-                "queueing ieee80211 work while going to suspend\n"))
+       if (local->quiescing || (local->suspended && !local->resuming)) {
+               pr_warn("queueing ieee80211 work while going to suspend\n");
                return false;
+       }
 
        return true;
 }