diff options
Diffstat (limited to 'multitech/recipes/compat-wireless/ti-compat-wireless-wl12xx-r5.sp4.01/0002-wl12xx-Decrease-number-of-TX-transactions.patch')
-rwxr-xr-x | multitech/recipes/compat-wireless/ti-compat-wireless-wl12xx-r5.sp4.01/0002-wl12xx-Decrease-number-of-TX-transactions.patch | 139 |
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 + |