wl12xx: use freezable workqueue for netstack_work
authorEliad Peller <eliad@wizery.com>
Tue, 7 Jun 2011 09:50:46 +0000 (12:50 +0300)
committerLuciano Coelho <coelho@ti.com>
Mon, 27 Jun 2011 10:56:14 +0000 (13:56 +0300)
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>
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/wl12xx.h

index c9f59ce04746a3f95b3c84afbc74baf204aab413..ab3aa45db07b993f6b49a9b87a68f17e770c3d54 100644 (file)
@@ -4138,6 +4138,12 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
        INIT_WORK(&wl->rx_streaming_disable_work,
                  wl1271_rx_streaming_disable_work);
 
+       wl->freezable_wq = create_freezable_workqueue("wl12xx_wq");
+       if (!wl->freezable_wq) {
+               ret = -ENOMEM;
+               goto err_hw;
+       }
+
        wl->channel = WL1271_DEFAULT_CHANNEL;
        wl->beacon_int = WL1271_DEFAULT_BEACON_INT;
        wl->default_key = 0;
@@ -4182,7 +4188,7 @@ struct ieee80211_hw *wl1271_alloc_hw(void)
        wl->aggr_buf = (u8 *)__get_free_pages(GFP_KERNEL, order);
        if (!wl->aggr_buf) {
                ret = -ENOMEM;
-               goto err_hw;
+               goto err_wq;
        }
 
        wl->dummy_packet = wl12xx_alloc_dummy_packet(wl);
@@ -4227,6 +4233,9 @@ err_dummy_packet:
 err_aggr:
        free_pages((unsigned long)wl->aggr_buf, order);
 
+err_wq:
+       destroy_workqueue(wl->freezable_wq);
+
 err_hw:
        wl1271_debugfs_exit(wl);
        kfree(plat_dev);
@@ -4257,6 +4266,7 @@ int wl1271_free_hw(struct wl1271 *wl)
 
        kfree(wl->fw_status);
        kfree(wl->tx_res_if);
+       destroy_workqueue(wl->freezable_wq);
 
        ieee80211_free_hw(wl->hw);
 
index db230a503bf773d4c5fde61dcf4145ac0f90b100..9357695340cf2c9612dd9f5f4803e583325fca5c 100644 (file)
@@ -150,7 +150,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length)
        skb_trim(skb, skb->len - desc->pad_len);
 
        skb_queue_tail(&wl->deferred_rx_queue, skb);
-       ieee80211_queue_work(wl->hw, &wl->netstack_work);
+       queue_work(wl->freezable_wq, &wl->netstack_work);
 
        return is_data;
 }
index b2635c7ecee83b3d162f483098deaaa51f40d148..200590c0d9e3484ef2192d6e89a8c7ba4e0cdb3e 100644 (file)
@@ -727,7 +727,7 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
 
        /* return the packet to the stack */
        skb_queue_tail(&wl->deferred_tx_queue, skb);
-       ieee80211_queue_work(wl->hw, &wl->netstack_work);
+       queue_work(wl->freezable_wq, &wl->netstack_work);
        wl1271_free_tx_id(wl, result->id);
 }
 
index 145a14c22583fa1d36d27a13f4eac77b50763666..bbf4ee6d41029ce85062d55a1f15fde7e1b7df72 100644 (file)
@@ -445,6 +445,7 @@ struct wl1271 {
        struct sk_buff_head deferred_tx_queue;
 
        struct work_struct tx_work;
+       struct workqueue_struct *freezable_wq;
 
        /* Pending TX frames */
        unsigned long tx_frames_map[BITS_TO_LONGS(ACX_TX_DESCRIPTORS)];