aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReinette Chatre <reinette.chatre@intel.com>2010-04-13 19:11:19 -0400
committerReinette Chatre <reinette.chatre@intel.com>2010-05-10 18:09:02 -0400
commit3bce6066263efb5733ee2141ac8b56684fb3b0a7 (patch)
tree00e5fcac1a01c703e0a89c30542706699091fd61
parent2c810ccdbac434ae38f4ec5331d3f047dc90f98a (diff)
iwlagn: work around rate scaling reset delay
When station is using an HT channel to communicate to AP and communication is lost then driver will first be notified that channel is not an HT channel anymore before AP station is removed. A consequence of that is that the driver will know that it is not communicating on HT anymore, but the rate scaling table is still under the impression it is operating in HT. Any time after driver has been notified channel is not HT anymore there will thus be a firmware SYSASSERT when the current active LQ command is sent. A workaround for this issue is to not send a LQ command in the short time between being notified channel is not HT anymore and rate scaling table being updated. This fixes http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2173 Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c38
1 files changed, 37 insertions, 1 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 7e51647cf02d..e95282b93c3a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1170,6 +1170,39 @@ static inline void iwl_dump_lq_cmd(struct iwl_priv *priv,
1170#endif 1170#endif
1171 1171
1172/** 1172/**
1173 * is_lq_table_valid() - Test one aspect of LQ cmd for validity
1174 *
1175 * It sometimes happens when a HT rate has been in use and we
1176 * loose connectivity with AP then mac80211 will first tell us that the
1177 * current channel is not HT anymore before removing the station. In such a
1178 * scenario the RXON flags will be updated to indicate we are not
1179 * communicating HT anymore, but the LQ command may still contain HT rates.
1180 * Test for this to prevent driver from sending LQ command between the time
1181 * RXON flags are updated and when LQ command is updated.
1182 */
1183static bool is_lq_table_valid(struct iwl_priv *priv,
1184 struct iwl_link_quality_cmd *lq)
1185{
1186 int i;
1187 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
1188
1189 if (ht_conf->is_ht)
1190 return true;
1191
1192 IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n",
1193 priv->active_rxon.channel);
1194 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
1195 if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) {
1196 IWL_DEBUG_INFO(priv,
1197 "index %d of LQ expects HT channel\n",
1198 i);
1199 return false;
1200 }
1201 }
1202 return true;
1203}
1204
1205/**
1173 * iwl_send_lq_cmd() - Send link quality command 1206 * iwl_send_lq_cmd() - Send link quality command
1174 * @init: This command is sent as part of station initialization right 1207 * @init: This command is sent as part of station initialization right
1175 * after station has been added. 1208 * after station has been added.
@@ -1198,7 +1231,10 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
1198 iwl_dump_lq_cmd(priv, lq); 1231 iwl_dump_lq_cmd(priv, lq);
1199 BUG_ON(init && (cmd.flags & CMD_ASYNC)); 1232 BUG_ON(init && (cmd.flags & CMD_ASYNC));
1200 1233
1201 ret = iwl_send_cmd(priv, &cmd); 1234 if (is_lq_table_valid(priv, lq))
1235 ret = iwl_send_cmd(priv, &cmd);
1236 else
1237 ret = -EINVAL;
1202 1238
1203 if (cmd.flags & CMD_ASYNC) 1239 if (cmd.flags & CMD_ASYNC)
1204 return ret; 1240 return ret;