wl1251: do tx as soon as there's space
[pandora-kernel.git] / drivers / net / wireless / wl1251 / main.c
index b04da83..42b8df5 100644 (file)
@@ -279,9 +279,18 @@ irqreturn_t wl1251_irq(int irq, void *cookie)
                        goto out_sleep;
                }
 
+               if (intr & WL1251_ACX_INTR_TX_RESULT) {
+                       wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
+                       wl1251_tx_complete(wl);
+               }
+
                if (intr & WL1251_ACX_INTR_RX0_DATA) {
                        wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_RX0_DATA");
                        wl1251_rx(wl);
+
+                       if ((intr & WL1251_ACX_INTR_RX1_DATA)
+                           && skb_queue_len(&wl->tx_queue) > 0)
+                               wl1251_tx_work_unlocked(wl, false);
                }
 
                if (intr & WL1251_ACX_INTR_RX1_DATA) {
@@ -289,11 +298,6 @@ irqreturn_t wl1251_irq(int irq, void *cookie)
                        wl1251_rx(wl);
                }
 
-               if (intr & WL1251_ACX_INTR_TX_RESULT) {
-                       wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_TX_RESULT");
-                       wl1251_tx_complete(wl);
-               }
-
                if (intr & WL1251_ACX_INTR_EVENT_A) {
                        wl1251_debug(DEBUG_IRQ, "WL1251_ACX_INTR_EVENT_A");
                        wl1251_event_handle(wl, 0);
@@ -308,21 +312,8 @@ irqreturn_t wl1251_irq(int irq, void *cookie)
                        wl1251_debug(DEBUG_IRQ,
                                     "WL1251_ACX_INTR_INIT_COMPLETE");
 
-               while (skb_queue_len(&wl->tx_queue) > 0
-                      && wl1251_tx_path_status(wl) == 0) {
-
-                       struct sk_buff *skb = skb_dequeue(&wl->tx_queue);
-                       if (skb == NULL)
-                               goto out_sleep;
-
-                       ret = wl1251_tx_frame(wl, skb);
-                       if (ret == -EBUSY) {
-                               skb_queue_head(&wl->tx_queue, skb);
-                               break;
-                       } else if (ret < 0) {
-                               dev_kfree_skb(skb);
-                       }
-               }
+               if (skb_queue_len(&wl->tx_queue) > 0)
+                       wl1251_tx_work_unlocked(wl, false);
 
                if (--ctr == 0)
                        break;
@@ -654,8 +645,9 @@ static void wl1251_ps_work(struct work_struct *work)
                }
        }
 
-       need_ps = wl->psm_requested && !wl->bss_lost;
        have_ps = wl->station_mode == STATION_POWER_SAVE_MODE;
+       need_ps = wl->psm_requested && !wl->bss_lost
+               && wl->rate < wl->ps_rate_threshold;
 
        if (need_ps == have_ps) {
                //wl1251_info("ps: already in mode %d", have_ps);
@@ -674,13 +666,6 @@ static void wl1251_ps_work(struct work_struct *work)
                if (diff < msecs_to_jiffies(3000))
                        wait += msecs_to_jiffies(1000);
 
-               diff = jiffies - wl->last_io_jiffies;
-               if (diff < msecs_to_jiffies(150)) {
-                       //wl1251_info("ps: postponed psm, j %ld", diff);
-                       if (wait < msecs_to_jiffies(150) - diff + 1)
-                               wait = msecs_to_jiffies(150) - diff + 1;
-               }
-
                for (i = 0; i < ARRAY_SIZE(wl->tx_frames); i++) {
                        if (wl->tx_frames[i] != NULL) {
                                //wl1251_error("  frm %d busy", i);
@@ -709,8 +694,7 @@ static void wl1251_ps_work(struct work_struct *work)
        if (ret < 0)
                goto out_sleep;
 
-       //wl1251_info("psm %d, j %ld, d %ld", need_ps,
-       //      jiffies - wl->last_io_jiffies);
+       // wl1251_info("psm %d, r %u", need_ps, wl->rate);
 
 out_sleep:
        wl1251_ps_elp_sleep(wl);
@@ -1689,6 +1673,7 @@ struct ieee80211_hw *wl1251_alloc_hw(void)
        wl->beacon_int = WL1251_DEFAULT_BEACON_INT;
        wl->dtim_period = WL1251_DEFAULT_DTIM_PERIOD;
        wl->vif = NULL;
+       wl->ps_rate_threshold = 100000;
 
        for (i = 0; i < FW_TX_CMPLT_BLOCK_SIZE; i++)
                wl->tx_frames[i] = NULL;