aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2010-11-10 12:56:43 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-11-15 13:26:49 -0500
commit35a6eb36520b938742d8680fd8d821df20982ced (patch)
treec353b73bf8175c20f62dbcd1c45cfa722b39be45 /drivers/net
parentfd11743dd25efe7157ff17b03dd2db0cbb6fed05 (diff)
iwlwifi: resending QoS command when HT changes
"mac80211: Fix WMM driver queue configuration" inadvertedly broke iwlwifi, because now mac80211 configures the QoS settings before assoc, and therefore before HT. Thus, iwlwifi no longer told the device about the HT setting, which it needs to -- and thus throughput went down a lot. Fix this by resending the QoS command to the device not only when QoS/WMM settings change, but also when HT changes. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rxon.c65
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-legacy.c60
2 files changed, 69 insertions, 56 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
index f0ddfb1a9c87..02288779a71f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
@@ -269,6 +269,34 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
269 return 0; 269 return 0;
270} 270}
271 271
272static void iwlagn_update_qos(struct iwl_priv *priv,
273 struct iwl_rxon_context *ctx)
274{
275 int ret;
276
277 if (!ctx->is_active)
278 return;
279
280 ctx->qos_data.def_qos_parm.qos_flags = 0;
281
282 if (ctx->qos_data.qos_active)
283 ctx->qos_data.def_qos_parm.qos_flags |=
284 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
285
286 if (ctx->ht.enabled)
287 ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
288
289 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
290 ctx->qos_data.qos_active,
291 ctx->qos_data.def_qos_parm.qos_flags);
292
293 ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd,
294 sizeof(struct iwl_qosparam_cmd),
295 &ctx->qos_data.def_qos_parm);
296 if (ret)
297 IWL_ERR(priv, "Failed to update QoS\n");
298}
299
272int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed) 300int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
273{ 301{
274 struct iwl_priv *priv = hw->priv; 302 struct iwl_priv *priv = hw->priv;
@@ -277,6 +305,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
277 struct ieee80211_channel *channel = conf->channel; 305 struct ieee80211_channel *channel = conf->channel;
278 const struct iwl_channel_info *ch_info; 306 const struct iwl_channel_info *ch_info;
279 int ret = 0; 307 int ret = 0;
308 bool ht_changed[NUM_IWL_RXON_CTX] = {};
280 309
281 IWL_DEBUG_MAC80211(priv, "changed %#x", changed); 310 IWL_DEBUG_MAC80211(priv, "changed %#x", changed);
282 311
@@ -324,7 +353,11 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
324 353
325 for_each_context(priv, ctx) { 354 for_each_context(priv, ctx) {
326 /* Configure HT40 channels */ 355 /* Configure HT40 channels */
327 ctx->ht.enabled = conf_is_ht(conf); 356 if (ctx->ht.enabled != conf_is_ht(conf)) {
357 ctx->ht.enabled = conf_is_ht(conf);
358 ht_changed[ctx->ctxid] = true;
359 }
360
328 if (ctx->ht.enabled) { 361 if (ctx->ht.enabled) {
329 if (conf_is_ht40_minus(conf)) { 362 if (conf_is_ht40_minus(conf)) {
330 ctx->ht.extension_chan_offset = 363 ctx->ht.extension_chan_offset =
@@ -392,40 +425,14 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
392 if (!memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) 425 if (!memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
393 continue; 426 continue;
394 iwlagn_commit_rxon(priv, ctx); 427 iwlagn_commit_rxon(priv, ctx);
428 if (ht_changed[ctx->ctxid])
429 iwlagn_update_qos(priv, ctx);
395 } 430 }
396 out: 431 out:
397 mutex_unlock(&priv->mutex); 432 mutex_unlock(&priv->mutex);
398 return ret; 433 return ret;
399} 434}
400 435
401static void iwlagn_update_qos(struct iwl_priv *priv,
402 struct iwl_rxon_context *ctx)
403{
404 int ret;
405
406 if (!ctx->is_active)
407 return;
408
409 ctx->qos_data.def_qos_parm.qos_flags = 0;
410
411 if (ctx->qos_data.qos_active)
412 ctx->qos_data.def_qos_parm.qos_flags |=
413 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
414
415 if (ctx->ht.enabled)
416 ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
417
418 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
419 ctx->qos_data.qos_active,
420 ctx->qos_data.def_qos_parm.qos_flags);
421
422 ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd,
423 sizeof(struct iwl_qosparam_cmd),
424 &ctx->qos_data.def_qos_parm);
425 if (ret)
426 IWL_ERR(priv, "Failed to update QoS\n");
427}
428
429static void iwlagn_check_needed_chains(struct iwl_priv *priv, 436static void iwlagn_check_needed_chains(struct iwl_priv *priv,
430 struct iwl_rxon_context *ctx, 437 struct iwl_rxon_context *ctx,
431 struct ieee80211_bss_conf *bss_conf) 438 struct ieee80211_bss_conf *bss_conf)
diff --git a/drivers/net/wireless/iwlwifi/iwl-legacy.c b/drivers/net/wireless/iwlwifi/iwl-legacy.c
index 10d9c4202875..a08b4e56e6b1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-legacy.c
+++ b/drivers/net/wireless/iwlwifi/iwl-legacy.c
@@ -34,6 +34,32 @@
34#include "iwl-helpers.h" 34#include "iwl-helpers.h"
35#include "iwl-legacy.h" 35#include "iwl-legacy.h"
36 36
37static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
38{
39 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
40 return;
41
42 if (!ctx->is_active)
43 return;
44
45 ctx->qos_data.def_qos_parm.qos_flags = 0;
46
47 if (ctx->qos_data.qos_active)
48 ctx->qos_data.def_qos_parm.qos_flags |=
49 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
50
51 if (ctx->ht.enabled)
52 ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
53
54 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
55 ctx->qos_data.qos_active,
56 ctx->qos_data.def_qos_parm.qos_flags);
57
58 iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
59 sizeof(struct iwl_qosparam_cmd),
60 &ctx->qos_data.def_qos_parm, NULL);
61}
62
37/** 63/**
38 * iwl_legacy_mac_config - mac80211 config callback 64 * iwl_legacy_mac_config - mac80211 config callback
39 */ 65 */
@@ -49,6 +75,7 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)
49 int ret = 0; 75 int ret = 0;
50 u16 ch; 76 u16 ch;
51 int scan_active = 0; 77 int scan_active = 0;
78 bool ht_changed[NUM_IWL_RXON_CTX] = {};
52 79
53 if (WARN_ON(!priv->cfg->ops->legacy)) 80 if (WARN_ON(!priv->cfg->ops->legacy))
54 return -EOPNOTSUPP; 81 return -EOPNOTSUPP;
@@ -100,7 +127,10 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)
100 127
101 for_each_context(priv, ctx) { 128 for_each_context(priv, ctx) {
102 /* Configure HT40 channels */ 129 /* Configure HT40 channels */
103 ctx->ht.enabled = conf_is_ht(conf); 130 if (ctx->ht.enabled != conf_is_ht(conf)) {
131 ctx->ht.enabled = conf_is_ht(conf);
132 ht_changed[ctx->ctxid] = true;
133 }
104 if (ctx->ht.enabled) { 134 if (ctx->ht.enabled) {
105 if (conf_is_ht40_minus(conf)) { 135 if (conf_is_ht40_minus(conf)) {
106 ctx->ht.extension_chan_offset = 136 ctx->ht.extension_chan_offset =
@@ -177,6 +207,8 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)
177 else 207 else
178 IWL_DEBUG_INFO(priv, 208 IWL_DEBUG_INFO(priv,
179 "Not re-sending same RXON configuration.\n"); 209 "Not re-sending same RXON configuration.\n");
210 if (ht_changed[ctx->ctxid])
211 iwl_update_qos(priv, ctx);
180 } 212 }
181 213
182out: 214out:
@@ -295,32 +327,6 @@ static void iwl_ht_conf(struct iwl_priv *priv,
295 IWL_DEBUG_ASSOC(priv, "leave\n"); 327 IWL_DEBUG_ASSOC(priv, "leave\n");
296} 328}
297 329
298static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
299{
300 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
301 return;
302
303 if (!ctx->is_active)
304 return;
305
306 ctx->qos_data.def_qos_parm.qos_flags = 0;
307
308 if (ctx->qos_data.qos_active)
309 ctx->qos_data.def_qos_parm.qos_flags |=
310 QOS_PARAM_FLG_UPDATE_EDCA_MSK;
311
312 if (ctx->ht.enabled)
313 ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;
314
315 IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
316 ctx->qos_data.qos_active,
317 ctx->qos_data.def_qos_parm.qos_flags);
318
319 iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
320 sizeof(struct iwl_qosparam_cmd),
321 &ctx->qos_data.def_qos_parm, NULL);
322}
323
324static inline void iwl_set_no_assoc(struct iwl_priv *priv, 330static inline void iwl_set_no_assoc(struct iwl_priv *priv,
325 struct ieee80211_vif *vif) 331 struct ieee80211_vif *vif)
326{ 332{