diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 7e51647cf02da601bef41b30592c035355d8b847..e95282b93c3a815b0f5f46d05be7523ffbacb783 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -1169,6 +1169,39 @@ static inline void iwl_dump_lq_cmd(struct iwl_priv *priv, } #endif +/** + * is_lq_table_valid() - Test one aspect of LQ cmd for validity + * + * It sometimes happens when a HT rate has been in use and we + * loose connectivity with AP then mac80211 will first tell us that the + * current channel is not HT anymore before removing the station. In such a + * scenario the RXON flags will be updated to indicate we are not + * communicating HT anymore, but the LQ command may still contain HT rates. + * Test for this to prevent driver from sending LQ command between the time + * RXON flags are updated and when LQ command is updated. + */ +static bool is_lq_table_valid(struct iwl_priv *priv, + struct iwl_link_quality_cmd *lq) +{ + int i; + struct iwl_ht_config *ht_conf = &priv->current_ht_config; + + if (ht_conf->is_ht) + return true; + + IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n", + priv->active_rxon.channel); + for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { + if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) { + IWL_DEBUG_INFO(priv, + "index %d of LQ expects HT channel\n", + i); + return false; + } + } + return true; +} + /** * iwl_send_lq_cmd() - Send link quality command * @init: This command is sent as part of station initialization right @@ -1198,7 +1231,10 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, iwl_dump_lq_cmd(priv, lq); BUG_ON(init && (cmd.flags & CMD_ASYNC)); - ret = iwl_send_cmd(priv, &cmd); + if (is_lq_table_valid(priv, lq)) + ret = iwl_send_cmd(priv, &cmd); + else + ret = -EINVAL; if (cmd.flags & CMD_ASYNC) return ret;