aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2011-06-07 05:50:46 -0400
committerLuciano Coelho <coelho@ti.com>2011-06-27 06:56:14 -0400
commit92ef8960aee2f840c6a54c968d40199843f015c0 (patch)
tree3554b6b9684c7fe5cfabdb9ea15a9dd2d3640f50 /drivers/net/wireless
parentc27d3accb6f06b0afedfe472dfe0c8e7d87ff0a6 (diff)
wl12xx: use freezable workqueue for netstack_work
When resuming (after wowlan), we want the rx packets (which is usually the wake-up packet itself) to be passed to mac80211 only after the resume notifier was completed, and mac80211 is up and running (otherwise, the packets will be dropped). By enqueueing the netstack_work to a freezable workqueue, we can guarantee the rx processing to occur only after mac80211 was resumed. Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Ido Yariv <ido@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/wl12xx/main.c12
-rw-r--r--drivers/net/wireless/wl12xx/rx.c2
-rw-r--r--drivers/net/wireless/wl12xx/tx.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl12xx.h1
4 files changed, 14 insertions, 3 deletions
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index c9f59ce04746..ab3aa45db07b 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -4138,6 +4138,12 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
4138 INIT_WORK(&wl->rx_streaming_disable_work, 4138 INIT_WORK(&wl->rx_streaming_disable_work,
4139 wl1271_rx_streaming_disable_work); 4139 wl1271_rx_streaming_disable_work);
4140 4140
4141 wl->freezable_wq = create_freezable_workqueue("wl12xx_wq");
4142 if (!wl->freezable_wq) {
4143 ret = -ENOMEM;
4144 goto err_hw;
4145 }
4146
4141 wl->channel = WL1271_DEFAULT_CHANNEL; 4147 wl->channel = WL1271_DEFAULT_CHANNEL;
4142 wl->beacon_int = WL1271_DEFAULT_BEACON_INT; 4148 wl->beacon_int = WL1271_DEFAULT_BEACON_INT;
4143 wl->default_key = 0; 4149 wl->default_key = 0;
@@ -4182,7 +4188,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
4182 wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order); 4188 wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
4183 if (!wl->aggr_buf) { 4189 if (!wl->aggr_buf) {
4184 ret = -ENOMEM; 4190 ret = -ENOMEM;
4185 goto err_hw; 4191 goto err_wq;
4186 } 4192 }
4187 4193
4188 wl->dummy_packet = wl12xx_alloc_dummy_packet(wl); 4194 wl->dummy_packet = wl12xx_alloc_dummy_packet(wl);
@@ -4227,6 +4233,9 @@ err_dummy_packet:
4227err_aggr: 4233err_aggr:
4228 free_pages((unsigned long)wl->aggr_buf, order); 4234 free_pages((unsigned long)wl->aggr_buf, order);
4229 4235
4236err_wq:
4237 destroy_workqueue(wl->freezable_wq);
4238
4230err_hw: 4239err_hw:
4231 wl1271_debugfs_exit(wl); 4240 wl1271_debugfs_exit(wl);
4232 kfree(plat_dev); 4241 kfree(plat_dev);
@@ -4257,6 +4266,7 @@ int wl1271_free_hw(struct wl1271 *wl)
4257 4266
4258 kfree(wl->fw_status); 4267 kfree(wl->fw_status);
4259 kfree(wl->tx_res_if); 4268 kfree(wl->tx_res_if);
4269 destroy_workqueue(wl->freezable_wq);
4260 4270
4261 ieee80211_free_hw(wl->hw); 4271 ieee80211_free_hw(wl->hw);
4262 4272
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
index db230a503bf7..9357695340cf 100644
--- a/drivers/net/wireless/wl12xx/rx.c
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -150,7 +150,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
150 skb_trim(skb, skb->len - desc->pad_len); 150 skb_trim(skb, skb->len - desc->pad_len);
151 151
152 skb_queue_tail(&wl->deferred_rx_queue, skb); 152 skb_queue_tail(&wl->deferred_rx_queue, skb);
153 ieee80211_queue_work(wl->hw, &wl->netstack_work); 153 queue_work(wl->freezable_wq, &wl->netstack_work);
154 154
155 return is_data; 155 return is_data;
156} 156}
diff --git a/drivers/net/wireless/wl12xx/tx.c b/drivers/net/wireless/wl12xx/tx.c
index b2635c7ecee8..200590c0d9e3 100644
--- a/drivers/net/wireless/wl12xx/tx.c
+++ b/drivers/net/wireless/wl12xx/tx.c
@@ -727,7 +727,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
727 727
728 /* return the packet to the stack */ 728 /* return the packet to the stack */
729 skb_queue_tail(&wl->deferred_tx_queue, skb); 729 skb_queue_tail(&wl->deferred_tx_queue, skb);
730 ieee80211_queue_work(wl->hw, &wl->netstack_work); 730 queue_work(wl->freezable_wq, &wl->netstack_work);
731 wl1271_free_tx_id(wl, result->id); 731 wl1271_free_tx_id(wl, result->id);
732} 732}
733 733
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 145a14c22583..bbf4ee6d4102 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -445,6 +445,7 @@ struct wl1271 {
445 struct sk_buff_head deferred_tx_queue; 445 struct sk_buff_head deferred_tx_queue;
446 446
447 struct work_struct tx_work; 447 struct work_struct tx_work;
448 struct workqueue_struct *freezable_wq;
448 449
449 /* Pending TX frames */ 450 /* Pending TX frames */
450 unsigned long tx_frames_map[BITS_TO_LONGS(ACX_TX_DESCRIPTORS)]; 451 unsigned long tx_frames_map[BITS_TO_LONGS(ACX_TX_DESCRIPTORS)];