Skip to content

Commit

Permalink
iwlwifi: resending QoS command when HT changes
Browse files Browse the repository at this point in the history
"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>
  • Loading branch information
Wey-Yi Guy authored and John W. Linville committed Nov 15, 2010
1 parent fd11743 commit 35a6eb3
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 56 deletions.
65 changes: 36 additions & 29 deletions drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,34 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
return 0;
}

static void iwlagn_update_qos(struct iwl_priv *priv,
struct iwl_rxon_context *ctx)
{
int ret;

if (!ctx->is_active)
return;

ctx->qos_data.def_qos_parm.qos_flags = 0;

if (ctx->qos_data.qos_active)
ctx->qos_data.def_qos_parm.qos_flags |=
QOS_PARAM_FLG_UPDATE_EDCA_MSK;

if (ctx->ht.enabled)
ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;

IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
ctx->qos_data.qos_active,
ctx->qos_data.def_qos_parm.qos_flags);

ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd,
sizeof(struct iwl_qosparam_cmd),
&ctx->qos_data.def_qos_parm);
if (ret)
IWL_ERR(priv, "Failed to update QoS\n");
}

int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
{
struct iwl_priv *priv = hw->priv;
Expand All @@ -277,6 +305,7 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
struct ieee80211_channel *channel = conf->channel;
const struct iwl_channel_info *ch_info;
int ret = 0;
bool ht_changed[NUM_IWL_RXON_CTX] = {};

IWL_DEBUG_MAC80211(priv, "changed %#x", changed);

Expand Down Expand Up @@ -324,7 +353,11 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)

for_each_context(priv, ctx) {
/* Configure HT40 channels */
ctx->ht.enabled = conf_is_ht(conf);
if (ctx->ht.enabled != conf_is_ht(conf)) {
ctx->ht.enabled = conf_is_ht(conf);
ht_changed[ctx->ctxid] = true;
}

if (ctx->ht.enabled) {
if (conf_is_ht40_minus(conf)) {
ctx->ht.extension_chan_offset =
Expand Down Expand Up @@ -392,40 +425,14 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
if (!memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
continue;
iwlagn_commit_rxon(priv, ctx);
if (ht_changed[ctx->ctxid])
iwlagn_update_qos(priv, ctx);
}
out:
mutex_unlock(&priv->mutex);
return ret;
}

static void iwlagn_update_qos(struct iwl_priv *priv,
struct iwl_rxon_context *ctx)
{
int ret;

if (!ctx->is_active)
return;

ctx->qos_data.def_qos_parm.qos_flags = 0;

if (ctx->qos_data.qos_active)
ctx->qos_data.def_qos_parm.qos_flags |=
QOS_PARAM_FLG_UPDATE_EDCA_MSK;

if (ctx->ht.enabled)
ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;

IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
ctx->qos_data.qos_active,
ctx->qos_data.def_qos_parm.qos_flags);

ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd,
sizeof(struct iwl_qosparam_cmd),
&ctx->qos_data.def_qos_parm);
if (ret)
IWL_ERR(priv, "Failed to update QoS\n");
}

static void iwlagn_check_needed_chains(struct iwl_priv *priv,
struct iwl_rxon_context *ctx,
struct ieee80211_bss_conf *bss_conf)
Expand Down
60 changes: 33 additions & 27 deletions drivers/net/wireless/iwlwifi/iwl-legacy.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,32 @@
#include "iwl-helpers.h"
#include "iwl-legacy.h"

static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;

if (!ctx->is_active)
return;

ctx->qos_data.def_qos_parm.qos_flags = 0;

if (ctx->qos_data.qos_active)
ctx->qos_data.def_qos_parm.qos_flags |=
QOS_PARAM_FLG_UPDATE_EDCA_MSK;

if (ctx->ht.enabled)
ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;

IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
ctx->qos_data.qos_active,
ctx->qos_data.def_qos_parm.qos_flags);

iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
sizeof(struct iwl_qosparam_cmd),
&ctx->qos_data.def_qos_parm, NULL);
}

/**
* iwl_legacy_mac_config - mac80211 config callback
*/
Expand All @@ -49,6 +75,7 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)
int ret = 0;
u16 ch;
int scan_active = 0;
bool ht_changed[NUM_IWL_RXON_CTX] = {};

if (WARN_ON(!priv->cfg->ops->legacy))
return -EOPNOTSUPP;
Expand Down Expand Up @@ -100,7 +127,10 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)

for_each_context(priv, ctx) {
/* Configure HT40 channels */
ctx->ht.enabled = conf_is_ht(conf);
if (ctx->ht.enabled != conf_is_ht(conf)) {
ctx->ht.enabled = conf_is_ht(conf);
ht_changed[ctx->ctxid] = true;
}
if (ctx->ht.enabled) {
if (conf_is_ht40_minus(conf)) {
ctx->ht.extension_chan_offset =
Expand Down Expand Up @@ -177,6 +207,8 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)
else
IWL_DEBUG_INFO(priv,
"Not re-sending same RXON configuration.\n");
if (ht_changed[ctx->ctxid])
iwl_update_qos(priv, ctx);
}

out:
Expand Down Expand Up @@ -295,32 +327,6 @@ static void iwl_ht_conf(struct iwl_priv *priv,
IWL_DEBUG_ASSOC(priv, "leave\n");
}

static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;

if (!ctx->is_active)
return;

ctx->qos_data.def_qos_parm.qos_flags = 0;

if (ctx->qos_data.qos_active)
ctx->qos_data.def_qos_parm.qos_flags |=
QOS_PARAM_FLG_UPDATE_EDCA_MSK;

if (ctx->ht.enabled)
ctx->qos_data.def_qos_parm.qos_flags |= QOS_PARAM_FLG_TGN_MSK;

IWL_DEBUG_QOS(priv, "send QoS cmd with Qos active=%d FLAGS=0x%X\n",
ctx->qos_data.qos_active,
ctx->qos_data.def_qos_parm.qos_flags);

iwl_send_cmd_pdu_async(priv, ctx->qos_cmd,
sizeof(struct iwl_qosparam_cmd),
&ctx->qos_data.def_qos_parm, NULL);
}

static inline void iwl_set_no_assoc(struct iwl_priv *priv,
struct ieee80211_vif *vif)
{
Expand Down

0 comments on commit 35a6eb3

Please sign in to comment.