return 0;
        }
 
+       /*
+        * Hardware/driver doesn't support hw_scan, so use software
+        * scanning instead. First send a nullfunc frame with power save
+        * bit on so that AP will buffer the frames for us while we are not
+        * listening, then send probe requests to each channel and wait for
+        * the responses. After all channels are scanned, tune back to the
+        * original channel and send a nullfunc frame with power save bit
+        * off to trigger the AP to send us all the buffered frames.
+        *
+        * Note that while local->sw_scanning is true everything else but
+        * nullfunc frames and probe requests will be dropped in
+        * ieee80211_tx_h_check_assoc().
+        */
        local->sw_scanning = true;
        if (local->ops->sw_scan_start)
                local->ops->sw_scan_start(local_to_hw(local));
 
                return TX_CONTINUE;
 
        if (unlikely(tx->local->sw_scanning) &&
-           !ieee80211_is_probe_req(hdr->frame_control))
+           !ieee80211_is_probe_req(hdr->frame_control) &&
+           !ieee80211_is_nullfunc(hdr->frame_control))
+               /*
+                * When software scanning only nullfunc frames (to notify
+                * the sleep state to the AP) and probe requests (for the
+                * active scan) are allowed, all other frames should not be
+                * sent and we should not get here, but if we do
+                * nonetheless, drop them to avoid sending them
+                * off-channel. See the link below and
+                * ieee80211_start_scan() for more.
+                *
+                * http://article.gmane.org/gmane.linux.kernel.wireless.general/30089
+                */
                return TX_DROP;
 
        if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT)