diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index bebfa28a171abbe598263bfd4af74afb94594382..8e75b09723b9578eb9ec0768b257191fe0981432 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -99,7 +99,7 @@ static void wl1271_debugfs_update_stats(struct wl1271 *wl)
 
 	mutex_lock(&wl->mutex);
 
-	ret = wl1271_ps_elp_wakeup(wl, false);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out;
 
diff --git a/drivers/net/wireless/wl12xx/io.h b/drivers/net/wireless/wl12xx/io.h
index 844b32b170bb615cfd5102c36996ee47be0b8570..c1aac8292089209f707de7b06e9e50817d3c4eea 100644
--- a/drivers/net/wireless/wl12xx/io.h
+++ b/drivers/net/wireless/wl12xx/io.h
@@ -168,5 +168,6 @@ void wl1271_unregister_hw(struct wl1271 *wl);
 int wl1271_init_ieee80211(struct wl1271 *wl);
 struct ieee80211_hw *wl1271_alloc_hw(void);
 int wl1271_free_hw(struct wl1271 *wl);
+irqreturn_t wl1271_irq(int irq, void *data);
 
 #endif
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index ba34ac3a440d1dc57836f97bef4c8c0263189e4e..f408c5a84cc912ff65784e0e6cbb6534499b05ca 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -374,7 +374,7 @@ static int wl1271_dev_notify(struct notifier_block *me, unsigned long what,
 	if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
 		goto out;
 
-	ret = wl1271_ps_elp_wakeup(wl, false);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out;
 
@@ -635,16 +635,39 @@ static void wl1271_fw_status(struct wl1271 *wl,
 		(s64)le32_to_cpu(status->fw_localtime);
 }
 
-#define WL1271_IRQ_MAX_LOOPS 10
+static void wl1271_flush_deferred_work(struct wl1271 *wl)
+{
+	struct sk_buff *skb;
+
+	/* Pass all received frames to the network stack */
+	while ((skb = skb_dequeue(&wl->deferred_rx_queue)))
+		ieee80211_rx_ni(wl->hw, skb);
+
+	/* Return sent skbs to the network stack */
+	while ((skb = skb_dequeue(&wl->deferred_tx_queue)))
+		ieee80211_tx_status(wl->hw, skb);
+}
+
+static void wl1271_netstack_work(struct work_struct *work)
+{
+	struct wl1271 *wl =
+		container_of(work, struct wl1271, netstack_work);
+
+	do {
+		wl1271_flush_deferred_work(wl);
+	} while (skb_queue_len(&wl->deferred_rx_queue));
+}
 
-static void wl1271_irq_work(struct work_struct *work)
+#define WL1271_IRQ_MAX_LOOPS 256
+
+irqreturn_t wl1271_irq(int irq, void *cookie)
 {
 	int ret;
 	u32 intr;
 	int loopcount = WL1271_IRQ_MAX_LOOPS;
-	unsigned long flags;
-	struct wl1271 *wl =
-		container_of(work, struct wl1271, irq_work);
+	struct wl1271 *wl = (struct wl1271 *)cookie;
+	bool done = false;
+	unsigned int defer_count;
 
 	mutex_lock(&wl->mutex);
 
@@ -653,26 +676,27 @@ static void wl1271_irq_work(struct work_struct *work)
 	if (unlikely(wl->state == WL1271_STATE_OFF))
 		goto out;
 
-	ret = wl1271_ps_elp_wakeup(wl, true);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out;
 
-	spin_lock_irqsave(&wl->wl_lock, flags);
-	while (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags) && loopcount) {
-		clear_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags);
-		spin_unlock_irqrestore(&wl->wl_lock, flags);
-		loopcount--;
+	while (!done && loopcount--) {
+		/*
+		 * In order to avoid a race with the hardirq, clear the flag
+		 * before acknowledging the chip. Since the mutex is held,
+		 * wl1271_ps_elp_wakeup cannot be called concurrently.
+		 */
+		clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
+		smp_mb__after_clear_bit();
 
 		wl1271_fw_status(wl, wl->fw_status);
 		intr = le32_to_cpu(wl->fw_status->common.intr);
+		intr &= WL1271_INTR_MASK;
 		if (!intr) {
-			wl1271_debug(DEBUG_IRQ, "Zero interrupt received.");
-			spin_lock_irqsave(&wl->wl_lock, flags);
+			done = true;
 			continue;
 		}
 
-		intr &= WL1271_INTR_MASK;
-
 		if (unlikely(intr & WL1271_ACX_INTR_WATCHDOG)) {
 			wl1271_error("watchdog interrupt received! "
 				     "starting recovery.");
@@ -682,7 +706,7 @@ static void wl1271_irq_work(struct work_struct *work)
 			goto out;
 		}
 
-		if (intr & WL1271_ACX_INTR_DATA) {
+		if (likely(intr & WL1271_ACX_INTR_DATA)) {
 			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
 
 			wl1271_rx(wl, &wl->fw_status->common);
@@ -701,6 +725,12 @@ static void wl1271_irq_work(struct work_struct *work)
 			if (wl->fw_status->common.tx_results_counter !=
 			    (wl->tx_results_count & 0xff))
 				wl1271_tx_complete(wl);
+
+			/* Make sure the deferred queues don't get too long */
+			defer_count = skb_queue_len(&wl->deferred_tx_queue) +
+				      skb_queue_len(&wl->deferred_rx_queue);
+			if (defer_count > WL1271_DEFERRED_QUEUE_LIMIT)
+				wl1271_flush_deferred_work(wl);
 		}
 
 		if (intr & WL1271_ACX_INTR_EVENT_A) {
@@ -719,21 +749,16 @@ static void wl1271_irq_work(struct work_struct *work)
 
 		if (intr & WL1271_ACX_INTR_HW_AVAILABLE)
 			wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_HW_AVAILABLE");
-
-		spin_lock_irqsave(&wl->wl_lock, flags);
 	}
 
-	if (test_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags))
-		ieee80211_queue_work(wl->hw, &wl->irq_work);
-	else
-		clear_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
-	spin_unlock_irqrestore(&wl->wl_lock, flags);
-
 	wl1271_ps_elp_sleep(wl);
 
 out:
 	mutex_unlock(&wl->mutex);
+
+	return IRQ_HANDLED;
 }
+EXPORT_SYMBOL_GPL(wl1271_irq);
 
 static int wl1271_fetch_firmware(struct wl1271 *wl)
 {
@@ -974,7 +999,6 @@ int wl1271_plt_start(struct wl1271 *wl)
 		goto out;
 
 irq_disable:
-		wl1271_disable_interrupts(wl);
 		mutex_unlock(&wl->mutex);
 		/* Unlocking the mutex in the middle of handling is
 		   inherently unsafe. In this case we deem it safe to do,
@@ -983,7 +1007,9 @@ irq_disable:
 		   work function will not do anything.) Also, any other
 		   possible concurrent operations will fail due to the
 		   current state, hence the wl1271 struct should be safe. */
-		cancel_work_sync(&wl->irq_work);
+		wl1271_disable_interrupts(wl);
+		wl1271_flush_deferred_work(wl);
+		cancel_work_sync(&wl->netstack_work);
 		mutex_lock(&wl->mutex);
 power_off:
 		wl1271_power_off(wl);
@@ -1010,14 +1036,15 @@ int __wl1271_plt_stop(struct wl1271 *wl)
 		goto out;
 	}
 
-	wl1271_disable_interrupts(wl);
 	wl1271_power_off(wl);
 
 	wl->state = WL1271_STATE_OFF;
 	wl->rx_counter = 0;
 
 	mutex_unlock(&wl->mutex);
-	cancel_work_sync(&wl->irq_work);
+	wl1271_disable_interrupts(wl);
+	wl1271_flush_deferred_work(wl);
+	cancel_work_sync(&wl->netstack_work);
 	cancel_work_sync(&wl->recovery_work);
 	mutex_lock(&wl->mutex);
 out:
@@ -1169,7 +1196,6 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
 		break;
 
 irq_disable:
-		wl1271_disable_interrupts(wl);
 		mutex_unlock(&wl->mutex);
 		/* Unlocking the mutex in the middle of handling is
 		   inherently unsafe. In this case we deem it safe to do,
@@ -1178,7 +1204,9 @@ irq_disable:
 		   work function will not do anything.) Also, any other
 		   possible concurrent operations will fail due to the
 		   current state, hence the wl1271 struct should be safe. */
-		cancel_work_sync(&wl->irq_work);
+		wl1271_disable_interrupts(wl);
+		wl1271_flush_deferred_work(wl);
+		cancel_work_sync(&wl->netstack_work);
 		mutex_lock(&wl->mutex);
 power_off:
 		wl1271_power_off(wl);
@@ -1244,12 +1272,12 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl)
 
 	wl->state = WL1271_STATE_OFF;
 
-	wl1271_disable_interrupts(wl);
-
 	mutex_unlock(&wl->mutex);
 
+	wl1271_disable_interrupts(wl);
+	wl1271_flush_deferred_work(wl);
 	cancel_delayed_work_sync(&wl->scan_complete_work);
-	cancel_work_sync(&wl->irq_work);
+	cancel_work_sync(&wl->netstack_work);
 	cancel_work_sync(&wl->tx_work);
 	cancel_delayed_work_sync(&wl->pspoll_work);
 	cancel_delayed_work_sync(&wl->elp_work);
@@ -1525,7 +1553,7 @@ static int wl1271_op_config(struct ieee80211_hw *hw, u32 changed)
 
 	is_ap = (wl->bss_type == BSS_TYPE_AP_BSS);
 
-	ret = wl1271_ps_elp_wakeup(wl, false);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out;
 
@@ -1681,7 +1709,7 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
 	if (unlikely(wl->state == WL1271_STATE_OFF))
 		goto out;
 
-	ret = wl1271_ps_elp_wakeup(wl, false);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out;
 
@@ -1910,7 +1938,7 @@ static int wl1271_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 		goto out_unlock;
 	}
 
-	ret = wl1271_ps_elp_wakeup(wl, false);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out_unlock;
 
@@ -2013,7 +2041,7 @@ static int wl1271_op_hw_scan(struct ieee80211_hw *hw,
 		goto out;
 	}
 
-	ret = wl1271_ps_elp_wakeup(wl, false);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out;
 
@@ -2039,7 +2067,7 @@ static int wl1271_op_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
 		goto out;
 	}
 
-	ret = wl1271_ps_elp_wakeup(wl, false);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out;
 
@@ -2067,7 +2095,7 @@ static int wl1271_op_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
 		goto out;
 	}
 
-	ret = wl1271_ps_elp_wakeup(wl, false);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out;
 
@@ -2546,7 +2574,7 @@ static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,
 	if (unlikely(wl->state == WL1271_STATE_OFF))
 		goto out;
 
-	ret = wl1271_ps_elp_wakeup(wl, false);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out;
 
@@ -2601,7 +2629,7 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
 		conf_tid->apsd_conf[0] = 0;
 		conf_tid->apsd_conf[1] = 0;
 	} else {
-		ret = wl1271_ps_elp_wakeup(wl, false);
+		ret = wl1271_ps_elp_wakeup(wl);
 		if (ret < 0)
 			goto out;
 
@@ -2647,7 +2675,7 @@ static u64 wl1271_op_get_tsf(struct ieee80211_hw *hw)
 	if (unlikely(wl->state == WL1271_STATE_OFF))
 		goto out;
 
-	ret = wl1271_ps_elp_wakeup(wl, false);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out;
 
@@ -2736,7 +2764,7 @@ static int wl1271_op_sta_add(struct ieee80211_hw *hw,
 	if (ret < 0)
 		goto out;
 
-	ret = wl1271_ps_elp_wakeup(wl, false);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out_free_sta;
 
@@ -2779,7 +2807,7 @@ static int wl1271_op_sta_remove(struct ieee80211_hw *hw,
 	if (WARN_ON(!test_bit(id, wl->ap_hlid_map)))
 		goto out;
 
-	ret = wl1271_ps_elp_wakeup(wl, false);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out;
 
@@ -2812,7 +2840,7 @@ int wl1271_op_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 		goto out;
 	}
 
-	ret = wl1271_ps_elp_wakeup(wl, false);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out;
 
@@ -3176,7 +3204,7 @@ static ssize_t wl1271_sysfs_store_bt_coex_state(struct device *dev,
 	if (wl->state == WL1271_STATE_OFF)
 		goto out;
 
-	ret = wl1271_ps_elp_wakeup(wl, false);
+	ret = wl1271_ps_elp_wakeup(wl);
 	if (ret < 0)
 		goto out;
 
@@ -3376,9 +3404,12 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
 		for (j = 0; j < AP_MAX_LINKS; j++)
 			skb_queue_head_init(&wl->links[j].tx_queue[i]);
 
+	skb_queue_head_init(&wl->deferred_rx_queue);
+	skb_queue_head_init(&wl->deferred_tx_queue);
+
 	INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
 	INIT_DELAYED_WORK(&wl->pspoll_work, wl1271_pspoll_work);
-	INIT_WORK(&wl->irq_work, wl1271_irq_work);
+	INIT_WORK(&wl->netstack_work, wl1271_netstack_work);
 	INIT_WORK(&wl->tx_work, wl1271_tx_work);
 	INIT_WORK(&wl->recovery_work, wl1271_recovery_work);
 	INIT_DELAYED_WORK(&wl->scan_complete_work, wl1271_scan_complete_work);
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
index 5c347b1bd17faae15f9150fb3a50ecfec370e264..971f13e792da0bf304c15f877ecdcb7d3c8bdf6a 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -69,7 +69,7 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
 	}
 }
 
-int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake)
+int wl1271_ps_elp_wakeup(struct wl1271 *wl)
 {
 	DECLARE_COMPLETION_ONSTACK(compl);
 	unsigned long flags;
@@ -87,7 +87,7 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake)
 	 * the completion variable in one entity.
 	 */
 	spin_lock_irqsave(&wl->wl_lock, flags);
-	if (work_pending(&wl->irq_work) || chip_awake)
+	if (test_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags))
 		pending = true;
 	else
 		wl->elp_compl = &compl;
@@ -149,7 +149,7 @@ int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
 	case STATION_ACTIVE_MODE:
 	default:
 		wl1271_debug(DEBUG_PSM, "leaving psm");
-		ret = wl1271_ps_elp_wakeup(wl, false);
+		ret = wl1271_ps_elp_wakeup(wl);
 		if (ret < 0)
 			return ret;
 
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h
index fc1f4c193593ee955267bb985b08765ca248a5b2..c41bd0a711bcd35e19855e6cb80c66a79cf0b4b4 100644
--- a/drivers/net/wireless/wl12xx/ps.h
+++ b/drivers/net/wireless/wl12xx/ps.h
@@ -30,7 +30,7 @@
 int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,
 		       u32 rates, bool send);
 void wl1271_ps_elp_sleep(struct wl1271 *wl);
-int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake);
+int wl1271_ps_elp_wakeup(struct wl1271 *wl);
 void wl1271_elp_work(struct work_struct *work);
 void wl1271_ps_link_start(struct wl1271 *wl, u8 hlid, bool clean_queues);
 void wl1271_ps_link_end(struct wl1271 *wl, u8 hlid);
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
index 4e7a3b311321a83315509c8d741c3764802ffdb0..919b59f00301bd8133babbf2538e749c9dddd51b 100644
--- a/drivers/net/wireless/wl12xx/rx.c
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -129,7 +129,8 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
 
 	skb_trim(skb, skb->len - desc->pad_len);
 
-	ieee80211_rx_ni(wl->hw, skb);
+	skb_queue_tail(&wl->deferred_rx_queue, skb);
+	ieee80211_queue_work(wl->hw, &wl->netstack_work);
 
 	return 0;
 }
diff --git a/drivers/net/wireless/wl12xx/sdio.c b/drivers/net/wireless/wl12xx/sdio.c
index 61fdc9e981bd05db90f54958cfe64706be09302f..b66abb5ebcf3c910156d7880e360054086441d7f 100644
--- a/drivers/net/wireless/wl12xx/sdio.c
+++ b/drivers/net/wireless/wl12xx/sdio.c
@@ -61,7 +61,7 @@ static struct device *wl1271_sdio_wl_to_dev(struct wl1271 *wl)
 	return &(wl_to_func(wl)->dev);
 }
 
-static irqreturn_t wl1271_irq(int irq, void *cookie)
+static irqreturn_t wl1271_hardirq(int irq, void *cookie)
 {
 	struct wl1271 *wl = cookie;
 	unsigned long flags;
@@ -70,17 +70,14 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
 
 	/* complete the ELP completion */
 	spin_lock_irqsave(&wl->wl_lock, flags);
+	set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
 	if (wl->elp_compl) {
 		complete(wl->elp_compl);
 		wl->elp_compl = NULL;
 	}
-
-	if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags))
-		ieee80211_queue_work(wl->hw, &wl->irq_work);
-	set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags);
 	spin_unlock_irqrestore(&wl->wl_lock, flags);
 
-	return IRQ_HANDLED;
+	return IRQ_WAKE_THREAD;
 }
 
 static void wl1271_sdio_disable_interrupts(struct wl1271 *wl)
@@ -243,14 +240,14 @@ static int __devinit wl1271_probe(struct sdio_func *func,
 	wl->irq = wlan_data->irq;
 	wl->ref_clock = wlan_data->board_ref_clock;
 
-	ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
+	ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq,
+				   IRQF_TRIGGER_RISING,
+				   DRIVER_NAME, wl);
 	if (ret < 0) {
 		wl1271_error("request_irq() failed: %d", ret);
 		goto out_free;
 	}
 
-	set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
-
 	disable_irq(wl->irq);
 
 	ret = wl1271_init_ieee80211(wl);
@@ -273,7 +270,6 @@ static int __devinit wl1271_probe(struct sdio_func *func,
  out_irq:
 	free_irq(wl->irq, wl);
 
-
  out_free:
 	wl1271_free_hw(wl);
 
diff --git a/drivers/net/wireless/wl12xx/spi.c b/drivers/net/wireless/wl12xx/spi.c
index 0132dad756c4c1bd73eb95738d505f9ba35febc4..df5a00f103ea4cac2b0e86e0cbe0f8b023f5a200 100644
--- a/drivers/net/wireless/wl12xx/spi.c
+++ b/drivers/net/wireless/wl12xx/spi.c
@@ -320,28 +320,23 @@ static void wl1271_spi_raw_write(struct wl1271 *wl, int addr, void *buf,
 	spi_sync(wl_to_spi(wl), &m);
 }
 
-static irqreturn_t wl1271_irq(int irq, void *cookie)
+static irqreturn_t wl1271_hardirq(int irq, void *cookie)
 {
-	struct wl1271 *wl;
+	struct wl1271 *wl = cookie;
 	unsigned long flags;
 
 	wl1271_debug(DEBUG_IRQ, "IRQ");
 
-	wl = cookie;
-
 	/* complete the ELP completion */
 	spin_lock_irqsave(&wl->wl_lock, flags);
+	set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags);
 	if (wl->elp_compl) {
 		complete(wl->elp_compl);
 		wl->elp_compl = NULL;
 	}
-
-	if (!test_and_set_bit(WL1271_FLAG_IRQ_RUNNING, &wl->flags))
-		ieee80211_queue_work(wl->hw, &wl->irq_work);
-	set_bit(WL1271_FLAG_IRQ_PENDING, &wl->flags);
 	spin_unlock_irqrestore(&wl->wl_lock, flags);
 
-	return IRQ_HANDLED;
+	return IRQ_WAKE_THREAD;
 }
 
 static int wl1271_spi_set_power(struct wl1271 *wl, bool enable)
@@ -413,14 +408,14 @@ static int __devinit wl1271_probe(struct spi_device *spi)
 		goto out_free;
 	}
 
-	ret = request_irq(wl->irq, wl1271_irq, 0, DRIVER_NAME, wl);
+	ret = request_threaded_irq(wl->irq, wl1271_hardirq, wl1271_irq,
+				   IRQF_TRIGGER_RISING,
+				   DRIVER_NAME, wl);
 	if (ret < 0) {
 		wl1271_error("request_irq() failed: %d", ret);
 		goto out_free;
 	}
 
-	set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
-
 	disable_irq(wl->irq);
 
 	ret = wl1271_init_ieee80211(wl);
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index 455954edf83ec6783149ca9b09fb0c3f93e49495..5e9ef7d53e7eeb5958aafc63467228ef6a0368cb 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -464,7 +464,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
 
 	while ((skb = wl1271_skb_dequeue(wl))) {
 		if (!woken_up) {
-			ret = wl1271_ps_elp_wakeup(wl, false);
+			ret = wl1271_ps_elp_wakeup(wl);
 			if (ret < 0)
 				goto out_ack;
 			woken_up = true;
@@ -589,7 +589,8 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
 		     result->rate_class_index, result->status);
 
 	/* return the packet to the stack */
-	ieee80211_tx_status(wl->hw, skb);
+	skb_queue_tail(&wl->deferred_tx_queue, skb);
+	ieee80211_queue_work(wl->hw, &wl->netstack_work);
 	wl1271_free_tx_id(wl, result->id);
 }
 
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index ea1eee7895cff12049c1053753ea45d417670ad8..e395c0c4ebbda7dd7afcf7d340a6f3dbce1cb7e5 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -320,7 +320,6 @@ enum wl12xx_flags {
 	WL1271_FLAG_IN_ELP,
 	WL1271_FLAG_PSM,
 	WL1271_FLAG_PSM_REQUESTED,
-	WL1271_FLAG_IRQ_PENDING,
 	WL1271_FLAG_IRQ_RUNNING,
 	WL1271_FLAG_IDLE,
 	WL1271_FLAG_IDLE_REQUESTED,
@@ -404,6 +403,12 @@ struct wl1271 {
 	struct sk_buff_head tx_queue[NUM_TX_QUEUES];
 	int tx_queue_count;
 
+	/* Frames received, not handled yet by mac80211 */
+	struct sk_buff_head deferred_rx_queue;
+
+	/* Frames sent, not returned yet to mac80211 */
+	struct sk_buff_head deferred_tx_queue;
+
 	struct work_struct tx_work;
 
 	/* Pending TX frames */
@@ -424,8 +429,8 @@ struct wl1271 {
 	/* Intermediate buffer, used for packet aggregation */
 	u8 *aggr_buf;
 
-	/* The target interrupt mask */
-	struct work_struct irq_work;
+	/* Network stack work  */
+	struct work_struct netstack_work;
 
 	/* Hardware recovery work */
 	struct work_struct recovery_work;
@@ -556,6 +561,8 @@ int wl1271_plt_stop(struct wl1271 *wl);
 #define WL1271_TX_QUEUE_LOW_WATERMARK  10
 #define WL1271_TX_QUEUE_HIGH_WATERMARK 25
 
+#define WL1271_DEFERRED_QUEUE_LIMIT    64
+
 /* WL1271 needs a 200ms sleep after power on, and a 20ms sleep before power
    on in case is has been shut down shortly before */
 #define WL1271_PRE_POWER_ON_SLEEP 20 /* in milliseconds */