summaryrefslogtreecommitdiff
path: root/multitech/recipes/compat-wireless/ti-compat-wireless-wl12xx-r5.sp4.01/0002-wl12xx-Decrease-number-of-TX-transactions.patch
diff options
context:
space:
mode:
Diffstat (limited to 'multitech/recipes/compat-wireless/ti-compat-wireless-wl12xx-r5.sp4.01/0002-wl12xx-Decrease-number-of-TX-transactions.patch')
-rwxr-xr-xmultitech/recipes/compat-wireless/ti-compat-wireless-wl12xx-r5.sp4.01/0002-wl12xx-Decrease-number-of-TX-transactions.patch139
1 files changed, 139 insertions, 0 deletions
diff --git a/multitech/recipes/compat-wireless/ti-compat-wireless-wl12xx-r5.sp4.01/0002-wl12xx-Decrease-number-of-TX-transactions.patch b/multitech/recipes/compat-wireless/ti-compat-wireless-wl12xx-r5.sp4.01/0002-wl12xx-Decrease-number-of-TX-transactions.patch
new file mode 100755
index 0000000..3e2185a
--- /dev/null
+++ b/multitech/recipes/compat-wireless/ti-compat-wireless-wl12xx-r5.sp4.01/0002-wl12xx-Decrease-number-of-TX-transactions.patch
@@ -0,0 +1,139 @@
+From a7807fffc76117a9d0a40fdcc85b56644e81f34c Mon Sep 17 00:00:00 2001
+From: Eyal Reizer <eyalr@ti.com>
+Date: Tue, 27 Nov 2012 16:05:20 +0200
+Subject: [PATCH] wl12xx: Decrease number of TX transactions
+
+On weak platforms, it is crucial to keep the number of SDIO transactions
+to a bare minimum. It is probably more important to keep CPU utilization
+low, than to handle FW events asap.
+
+In order to decrease the number of TX transactions, don't schedule tx
+work right away for every outgoing packet. Instead, try to wait for a
+short period before scheduling tx work if there aren't enough pending
+packets.
+
+In addition, increase the TX pacing timeout, so the FW will have enough
+free memory blocks for larger transfers.
+
+Adapted from original patch made by Ido Yariv <ido@wizery.com>
+Signed-off-by: Eyal Reizer <eyalr@ti.com>
+---
+ drivers/net/wireless/wl12xx/main.c | 39 ++++++++++++++++++++++++++++++----
+ drivers/net/wireless/wl12xx/wl12xx.h | 3 +++
+ 2 files changed, 38 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
+index c9888f4..a59ac43 100644
+--- a/drivers/net/wireless/wl12xx/main.c
++++ b/drivers/net/wireless/wl12xx/main.c
+@@ -218,8 +218,8 @@ static struct conf_drv_settings default_conf = {
+ },
+ },
+ .frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD,
+- .tx_compl_timeout = 700,
+- .tx_compl_threshold = 4,
++ .tx_compl_timeout = 1500,
++ .tx_compl_threshold = 6,
+ .basic_rate = CONF_HW_BIT_RATE_1MBPS,
+ .basic_rate_5 = CONF_HW_BIT_RATE_6MBPS,
+ .tmpl_short_retry_limit = 10,
+@@ -1199,6 +1199,8 @@ static int wl12xx_irq_locked(struct wl1271 *wl)
+ spin_lock_irqsave(&wl->wl_lock, flags);
+ if (!test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) &&
+ wl1271_tx_total_queue_count(wl) > 0) {
++ hrtimer_try_to_cancel(&wl->tx_timer);
++ clear_bit(WL1271_FLAG_TX_TIMER_SET, &wl->flags);
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+ /*
+ * In order to avoid starvation of the TX path,
+@@ -2056,6 +2058,9 @@ out:
+ return ret;
+ }
+
++#define TX_PACKETS_THRESHOLD 6
++#define TX_WORK_DELAY_NS (1500 * 1000)
++
+ static void wl1271_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+ {
+ struct wl1271 *wl = hw->priv;
+@@ -2113,14 +2118,37 @@ static void 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) &&
+- !test_bit(WL1271_FLAG_TX_PENDING, &wl->flags))
++ if (test_bit(WL1271_FLAG_FW_TX_BUSY, &wl->flags) ||
++ test_bit(WL1271_FLAG_TX_PENDING, &wl->flags))
++ goto out;
++
++ if (wl1271_tx_total_queue_count(wl) < TX_PACKETS_THRESHOLD) {
++ if (!test_and_set_bit(WL1271_FLAG_TX_TIMER_SET, &wl->flags))
++ hrtimer_start(&wl->tx_timer,
++ ktime_set(0, TX_WORK_DELAY_NS),
++ HRTIMER_MODE_REL);
++ } else {
++ hrtimer_try_to_cancel(&wl->tx_timer);
++ clear_bit(WL1271_FLAG_TX_TIMER_SET, &wl->flags);
+ ieee80211_queue_work(wl->hw, &wl->tx_work);
++ }
+
+ out:
+ spin_unlock_irqrestore(&wl->wl_lock, flags);
+ }
+
++enum hrtimer_restart wl12xx_tx_timer(struct hrtimer *timer)
++{
++ struct wl1271 *wl = container_of(timer, struct wl1271, tx_timer);
++ unsigned long flags;
++
++ spin_lock_irqsave(&wl->wl_lock, flags);
++ clear_bit(WL1271_FLAG_TX_TIMER_SET, &wl->flags);
++ ieee80211_queue_work(wl->hw, &wl->tx_work);
++ spin_unlock_irqrestore(&wl->wl_lock, flags);
++ return HRTIMER_NORESTART;
++}
++
+ int wl1271_tx_dummy_packet(struct wl1271 *wl)
+ {
+ unsigned long flags;
+@@ -2740,6 +2768,7 @@ static void wl1271_op_stop_locked(struct wl1271 *wl)
+ * held while doing so without deadlocking.
+ */
+ wlcore_disable_interrupts_nosync(wl);
++ hrtimer_cancel(&wl->tx_timer);
+ mutex_unlock(&wl->mutex);
+
+ mutex_lock(&wl_list_mutex);
+@@ -6798,6 +6827,8 @@ static struct ieee80211_hw *wl1271_alloc_hw(void)
+ wl->active_sta_count = 0;
+ wl->fwlog_size = 0;
+ init_waitqueue_head(&wl->fwlog_waitq);
++ hrtimer_init(&wl->tx_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
++ wl->tx_timer.function = wl12xx_tx_timer;
+
+ /* The system link is always allocated */
+ __set_bit(WL12XX_SYSTEM_HLID, wl->links_map);
+diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
+index 9c00dbf..e34f095 100644
+--- a/drivers/net/wireless/wl12xx/wl12xx.h
++++ b/drivers/net/wireless/wl12xx/wl12xx.h
+@@ -275,6 +275,7 @@ enum wl12xx_flags {
+ WL1271_FLAG_VIF_CHANGE_IN_PROGRESS,
+ WL1271_FLAG_INTENDED_FW_RECOVERY,
+ WL1271_FLAG_IO_FAILED,
++ WL1271_FLAG_TX_TIMER_SET,
+ };
+
+ enum wl12xx_vif_flags {
+@@ -594,6 +595,8 @@ struct wl1271 {
+
+ /* Patterns configured with set_rx_filters */
+ struct cfg80211_wowlan *wowlan_patterns;
++
++ struct hrtimer tx_timer;
+ };
+
+ struct wl1271_station {
+--
+1.7.9.5
+