aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEran Harary <eran.harary@intel.com>2015-02-08 06:58:50 -0500
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>2015-03-12 03:57:47 -0400
commitf4a3ee493e69239ad9e76e42524d08c58ac31f11 (patch)
tree5b213fc616db1231213bbb0854a60d6ff40e24db
parent82f0a9e602216e9216fa81a98bd3e38b030964cb (diff)
iwlwifi: mvm: Always enable the smart FIFO
We previously enabled the smart FIFO (SF) in BSS only after association. This cause interrupt latency on P2P on certain devices. Change the working model to enable the SF all the time and play with the timeout values based on the association state. This change was not tested on older firwmares, so make it happen only on -13.ucode and up. Signed-off-by: Eran Harary <eran.harary@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h14
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sf.c64
2 files changed, 68 insertions, 10 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index d89b0dd9e728..aab68cbae754 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -1447,7 +1447,19 @@ enum iwl_sf_scenario {
1447#define SF_W_MARK_LEGACY 4096 1447#define SF_W_MARK_LEGACY 4096
1448#define SF_W_MARK_SCAN 4096 1448#define SF_W_MARK_SCAN 4096
1449 1449
1450/* SF Scenarios timers for FULL_ON state (aligned to 32 uSec) */ 1450/* SF Scenarios timers for default configuration (aligned to 32 uSec) */
1451#define SF_SINGLE_UNICAST_IDLE_TIMER_DEF 160 /* 150 uSec */
1452#define SF_SINGLE_UNICAST_AGING_TIMER_DEF 400 /* 0.4 mSec */
1453#define SF_AGG_UNICAST_IDLE_TIMER_DEF 160 /* 150 uSec */
1454#define SF_AGG_UNICAST_AGING_TIMER_DEF 400 /* 0.4 mSec */
1455#define SF_MCAST_IDLE_TIMER_DEF 160 /* 150 mSec */
1456#define SF_MCAST_AGING_TIMER_DEF 400 /* 0.4 mSec */
1457#define SF_BA_IDLE_TIMER_DEF 160 /* 150 uSec */
1458#define SF_BA_AGING_TIMER_DEF 400 /* 0.4 mSec */
1459#define SF_TX_RE_IDLE_TIMER_DEF 160 /* 150 uSec */
1460#define SF_TX_RE_AGING_TIMER_DEF 400 /* 0.4 mSec */
1461
1462/* SF Scenarios timers for BSS MAC configuration (aligned to 32 uSec) */
1451#define SF_SINGLE_UNICAST_IDLE_TIMER 320 /* 300 uSec */ 1463#define SF_SINGLE_UNICAST_IDLE_TIMER 320 /* 300 uSec */
1452#define SF_SINGLE_UNICAST_AGING_TIMER 2016 /* 2 mSec */ 1464#define SF_SINGLE_UNICAST_AGING_TIMER 2016 /* 2 mSec */
1453#define SF_AGG_UNICAST_IDLE_TIMER 320 /* 300 uSec */ 1465#define SF_AGG_UNICAST_IDLE_TIMER 320 /* 300 uSec */
diff --git a/drivers/net/wireless/iwlwifi/mvm/sf.c b/drivers/net/wireless/iwlwifi/mvm/sf.c
index 4b9f6c6fb614..b0f59fdd287c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sf.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sf.c
@@ -99,7 +99,35 @@ static void iwl_mvm_bound_iface_iterator(void *_data, u8 *mac,
99 99
100/* 100/*
101 * Aging and idle timeouts for the different possible scenarios 101 * Aging and idle timeouts for the different possible scenarios
102 * in SF_FULL_ON state. 102 * in default configuration
103 */
104static const
105__le32 sf_full_timeout_def[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES] = {
106 {
107 cpu_to_le32(SF_SINGLE_UNICAST_AGING_TIMER_DEF),
108 cpu_to_le32(SF_SINGLE_UNICAST_IDLE_TIMER_DEF)
109 },
110 {
111 cpu_to_le32(SF_AGG_UNICAST_AGING_TIMER_DEF),
112 cpu_to_le32(SF_AGG_UNICAST_IDLE_TIMER_DEF)
113 },
114 {
115 cpu_to_le32(SF_MCAST_AGING_TIMER_DEF),
116 cpu_to_le32(SF_MCAST_IDLE_TIMER_DEF)
117 },
118 {
119 cpu_to_le32(SF_BA_AGING_TIMER_DEF),
120 cpu_to_le32(SF_BA_IDLE_TIMER_DEF)
121 },
122 {
123 cpu_to_le32(SF_TX_RE_AGING_TIMER_DEF),
124 cpu_to_le32(SF_TX_RE_IDLE_TIMER_DEF)
125 },
126};
127
128/*
129 * Aging and idle timeouts for the different possible scenarios
130 * in single BSS MAC configuration.
103 */ 131 */
104static const __le32 sf_full_timeout[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES] = { 132static const __le32 sf_full_timeout[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES] = {
105 { 133 {
@@ -124,7 +152,8 @@ static const __le32 sf_full_timeout[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES] = {
124 }, 152 },
125}; 153};
126 154
127static void iwl_mvm_fill_sf_command(struct iwl_sf_cfg_cmd *sf_cmd, 155static void iwl_mvm_fill_sf_command(struct iwl_mvm *mvm,
156 struct iwl_sf_cfg_cmd *sf_cmd,
128 struct ieee80211_sta *sta) 157 struct ieee80211_sta *sta)
129{ 158{
130 int i, j, watermark; 159 int i, j, watermark;
@@ -163,22 +192,37 @@ static void iwl_mvm_fill_sf_command(struct iwl_sf_cfg_cmd *sf_cmd,
163 cpu_to_le32(SF_LONG_DELAY_AGING_TIMER); 192 cpu_to_le32(SF_LONG_DELAY_AGING_TIMER);
164 } 193 }
165 } 194 }
166 BUILD_BUG_ON(sizeof(sf_full_timeout) !=
167 sizeof(__le32) * SF_NUM_SCENARIO * SF_NUM_TIMEOUT_TYPES);
168 195
169 memcpy(sf_cmd->full_on_timeouts, sf_full_timeout, 196 if (sta || IWL_UCODE_API(mvm->fw->ucode_ver) < 13) {
170 sizeof(sf_full_timeout)); 197 BUILD_BUG_ON(sizeof(sf_full_timeout) !=
198 sizeof(__le32) * SF_NUM_SCENARIO *
199 SF_NUM_TIMEOUT_TYPES);
200
201 memcpy(sf_cmd->full_on_timeouts, sf_full_timeout,
202 sizeof(sf_full_timeout));
203 } else {
204 BUILD_BUG_ON(sizeof(sf_full_timeout_def) !=
205 sizeof(__le32) * SF_NUM_SCENARIO *
206 SF_NUM_TIMEOUT_TYPES);
207
208 memcpy(sf_cmd->full_on_timeouts, sf_full_timeout_def,
209 sizeof(sf_full_timeout_def));
210 }
211
171} 212}
172 213
173static int iwl_mvm_sf_config(struct iwl_mvm *mvm, u8 sta_id, 214static int iwl_mvm_sf_config(struct iwl_mvm *mvm, u8 sta_id,
174 enum iwl_sf_state new_state) 215 enum iwl_sf_state new_state)
175{ 216{
176 struct iwl_sf_cfg_cmd sf_cmd = { 217 struct iwl_sf_cfg_cmd sf_cmd = {
177 .state = cpu_to_le32(new_state), 218 .state = cpu_to_le32(SF_FULL_ON),
178 }; 219 };
179 struct ieee80211_sta *sta; 220 struct ieee80211_sta *sta;
180 int ret = 0; 221 int ret = 0;
181 222
223 if (IWL_UCODE_API(mvm->fw->ucode_ver) < 13)
224 sf_cmd.state = cpu_to_le32(new_state);
225
182 if (mvm->cfg->disable_dummy_notification) 226 if (mvm->cfg->disable_dummy_notification)
183 sf_cmd.state |= cpu_to_le32(SF_CFG_DUMMY_NOTIF_OFF); 227 sf_cmd.state |= cpu_to_le32(SF_CFG_DUMMY_NOTIF_OFF);
184 228
@@ -191,6 +235,8 @@ static int iwl_mvm_sf_config(struct iwl_mvm *mvm, u8 sta_id,
191 235
192 switch (new_state) { 236 switch (new_state) {
193 case SF_UNINIT: 237 case SF_UNINIT:
238 if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 13)
239 iwl_mvm_fill_sf_command(mvm, &sf_cmd, NULL);
194 break; 240 break;
195 case SF_FULL_ON: 241 case SF_FULL_ON:
196 if (sta_id == IWL_MVM_STATION_COUNT) { 242 if (sta_id == IWL_MVM_STATION_COUNT) {
@@ -205,11 +251,11 @@ static int iwl_mvm_sf_config(struct iwl_mvm *mvm, u8 sta_id,
205 rcu_read_unlock(); 251 rcu_read_unlock();
206 return -EINVAL; 252 return -EINVAL;
207 } 253 }
208 iwl_mvm_fill_sf_command(&sf_cmd, sta); 254 iwl_mvm_fill_sf_command(mvm, &sf_cmd, sta);
209 rcu_read_unlock(); 255 rcu_read_unlock();
210 break; 256 break;
211 case SF_INIT_OFF: 257 case SF_INIT_OFF:
212 iwl_mvm_fill_sf_command(&sf_cmd, NULL); 258 iwl_mvm_fill_sf_command(mvm, &sf_cmd, NULL);
213 break; 259 break;
214 default: 260 default:
215 WARN_ONCE(1, "Invalid state: %d. not sending Smart Fifo cmd\n", 261 WARN_ONCE(1, "Invalid state: %d. not sending Smart Fifo cmd\n",