From patchwork Mon Oct 11 08:48:56 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Yariv X-Patchwork-Id: 244861 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o9B8njAa005126 for ; Mon, 11 Oct 2010 08:49:45 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753679Ab0JKItn (ORCPT ); Mon, 11 Oct 2010 04:49:43 -0400 Received: from mail-ww0-f44.google.com ([74.125.82.44]:34116 "EHLO mail-ww0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753621Ab0JKItm (ORCPT ); Mon, 11 Oct 2010 04:49:42 -0400 Received: by mail-ww0-f44.google.com with SMTP id 40so3490097wwj.1 for ; Mon, 11 Oct 2010 01:49:41 -0700 (PDT) Received: by 10.216.93.73 with SMTP id k51mr5165622wef.8.1286786981345; Mon, 11 Oct 2010 01:49:41 -0700 (PDT) Received: from localhost.localdomain (93-172-238-74.bb.netvision.net.il [93.172.238.74]) by mx.google.com with ESMTPS id p45sm4210838weq.21.2010.10.11.01.49.40 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 11 Oct 2010 01:49:41 -0700 (PDT) From: Ido Yariv To: Luciano Coelho , linux-wireless@vger.kernel.org Cc: Ido Yariv Subject: [PATCH 4/4] wl1271: Fix TX queue low watermark handling Date: Mon, 11 Oct 2010 10:48:56 +0200 Message-Id: <1286786936-20544-5-git-send-email-ido@wizery.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1286786936-20544-1-git-send-email-ido@wizery.com> References: <1286786936-20544-1-git-send-email-ido@wizery.com> Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Mon, 11 Oct 2010 08:49:45 +0000 (UTC) diff --git a/drivers/net/wireless/wl12xx/wl1271_tx.c b/drivers/net/wireless/wl12xx/wl1271_tx.c index e2ba5a7..a22ebb2 100644 --- a/drivers/net/wireless/wl12xx/wl1271_tx.c +++ b/drivers/net/wireless/wl12xx/wl1271_tx.c @@ -212,6 +212,20 @@ u32 wl1271_tx_enabled_rates_get(struct wl1271 *wl, u32 rate_set) return enabled_rates; } +static void handle_tx_low_watermark(struct wl1271 *wl) +{ + unsigned long flags; + + if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) && + skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) { + /* firmware buffer has space, restart queues */ + spin_lock_irqsave(&wl->wl_lock, flags); + ieee80211_wake_queues(wl->hw); + clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); + spin_unlock_irqrestore(&wl->wl_lock, flags); + } +} + void wl1271_tx_work_locked(struct wl1271 *wl) { struct sk_buff *skb; @@ -225,6 +239,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl) if (unlikely(test_and_clear_bit(WL1271_FLAG_STA_RATES_CHANGED, &wl->flags))) { unsigned long flags; + spin_lock_irqsave(&wl->wl_lock, flags); sta_rates = wl->sta_rate_set; spin_unlock_irqrestore(&wl->wl_lock, flags); @@ -289,6 +304,8 @@ out_ack: } out: + handle_tx_low_watermark(wl); + if (woken_up) wl1271_ps_elp_sleep(wl); } @@ -400,19 +417,6 @@ void wl1271_tx_complete(struct wl1271 *wl) wl->tx_results_count++; } - - if (test_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags) && - skb_queue_len(&wl->tx_queue) <= WL1271_TX_QUEUE_LOW_WATERMARK) { - unsigned long flags; - - /* firmware buffer has space, restart queues */ - wl1271_debug(DEBUG_TX, "tx_complete: waking queues"); - spin_lock_irqsave(&wl->wl_lock, flags); - ieee80211_wake_queues(wl->hw); - clear_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); - spin_unlock_irqrestore(&wl->wl_lock, flags); - ieee80211_queue_work(wl->hw, &wl->tx_work); - } } /* caller must hold wl->mutex */ @@ -427,6 +431,12 @@ void wl1271_tx_reset(struct wl1271 *wl) ieee80211_tx_status(wl->hw, skb); } + /* + * Make sure the driver is at a consistent state, in case this + * function is called from a context other than interface removal. + */ + handle_tx_low_watermark(wl); + for (i = 0; i < ACX_TX_DESCRIPTORS; i++) if (wl->tx_frames[i] != NULL) { skb = wl->tx_frames[i];