From patchwork Tue Mar 1 13:14:43 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ido Yariv X-Patchwork-Id: 599071 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 p21DFcDr012204 for ; Tue, 1 Mar 2011 13:15:38 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753049Ab1CANPh (ORCPT ); Tue, 1 Mar 2011 08:15:37 -0500 Received: from mail-ww0-f44.google.com ([74.125.82.44]:36990 "EHLO mail-ww0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752767Ab1CANPg (ORCPT ); Tue, 1 Mar 2011 08:15:36 -0500 Received: by mail-ww0-f44.google.com with SMTP id 22so4420741wwb.1 for ; Tue, 01 Mar 2011 05:15:36 -0800 (PST) Received: by 10.217.2.73 with SMTP id o51mr3618012wes.66.1298985336003; Tue, 01 Mar 2011 05:15:36 -0800 (PST) Received: from localhost.localdomain (93-173-12-148.bb.netvision.net.il [93.173.12.148]) by mx.google.com with ESMTPS id i80sm2467518wej.4.2011.03.01.05.15.25 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 01 Mar 2011 05:15:26 -0800 (PST) From: Ido Yariv To: Luciano Coelho Cc: linux-wireless@vger.kernel.org, Ido Yariv Subject: [PATCH v2 6/7] wl12xx: Avoid redundant TX work Date: Tue, 1 Mar 2011 15:14:43 +0200 Message-Id: <1298985284-6048-7-git-send-email-ido@wizery.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1298985284-6048-1-git-send-email-ido@wizery.com> References: <1298985284-6048-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.6 (demeter1.kernel.org [140.211.167.41]); Tue, 01 Mar 2011 13:15:38 +0000 (UTC) diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index 1a44f79..4e4aa42 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -668,6 +668,11 @@ irqreturn_t wl1271_irq(int irq, void *cookie) struct wl1271 *wl = (struct wl1271 *)cookie; bool done = false; unsigned int defer_count; + unsigned long flags; + + /* TX might be handled here, avoid redundant work */ + set_bit(WL1271_FLAG_TX_PENDING, &wl->flags); + cancel_work_sync(&wl->tx_work); mutex_lock(&wl->mutex); @@ -712,13 +717,17 @@ irqreturn_t wl1271_irq(int irq, void *cookie) wl1271_rx(wl, &wl->fw_status->common); /* Check if any tx blocks were freed */ + spin_lock_irqsave(&wl->wl_lock, flags); if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && wl->tx_queue_count) { + spin_unlock_irqrestore(&wl->wl_lock, flags); /* * In order to avoid starvation of the TX path, * call the work function directly. */ wl1271_tx_work_locked(wl); + } else { + spin_unlock_irqrestore(&wl->wl_lock, flags); } /* check for tx results */ @@ -754,6 +763,14 @@ irqreturn_t wl1271_irq(int irq, void *cookie) wl1271_ps_elp_sleep(wl); out: + spin_lock_irqsave(&wl->wl_lock, flags); + /* In case TX was not handled here, queue TX work */ + clear_bit(WL1271_FLAG_TX_PENDING, &wl->flags); + if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && + wl->tx_queue_count) + ieee80211_queue_work(wl->hw, &wl->tx_work); + spin_unlock_irqrestore(&wl->wl_lock, flags); + mutex_unlock(&wl->mutex); return IRQ_HANDLED; @@ -1068,7 +1085,13 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) int q; u8 hlid = 0; + q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); + + if (wl->bss_type == BSS_TYPE_AP_BSS) + hlid = wl1271_tx_get_hlid(skb); + spin_lock_irqsave(&wl->wl_lock, flags); + wl->tx_queue_count++; /* @@ -1081,12 +1104,8 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) set_bit(WL1271_FLAG_TX_QUEUE_STOPPED, &wl->flags); } - spin_unlock_irqrestore(&wl->wl_lock, flags); - /* queue the packet */ - q = wl1271_tx_get_queue(skb_get_queue_mapping(skb)); if (wl->bss_type == BSS_TYPE_AP_BSS) { - hlid = wl1271_tx_get_hlid(skb); wl1271_debug(DEBUG_TX, "queue skb hlid %d q %d", hlid, q); skb_queue_tail(&wl->links[hlid].tx_queue[q], skb); } else { @@ -1098,9 +1117,12 @@ static int wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * before that, the tx_work will not be initialized! */ - if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags)) + if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) && + !test_bit(WL1271_FLAG_TX_PENDING, &wl->flags)) ieee80211_queue_work(wl->hw, &wl->tx_work); + spin_unlock_irqrestore(&wl->wl_lock, flags); + return NETDEV_TX_OK; } diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h index 752dd93..b49f59d 100644 --- a/drivers/net/wireless/wl12xx/wl12xx.h +++ b/drivers/net/wireless/wl12xx/wl12xx.h @@ -317,6 +317,7 @@ enum wl12xx_flags { WL1271_FLAG_JOINED, WL1271_FLAG_GPIO_POWER, WL1271_FLAG_TX_QUEUE_STOPPED, + WL1271_FLAG_TX_PENDING, WL1271_FLAG_IN_ELP, WL1271_FLAG_PSM, WL1271_FLAG_PSM_REQUESTED,