@@ -1170,6 +1170,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
* after station has been added.
@@ -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;