Search Linux Wireless

[PATCH 1/8] iwlwifi: avoid ucode assert for LQ cmd call

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Mohamed Abbas <mabbas@xxxxxxxxxxxxxxx>

This patch make sure we don't call any Link Quality commands until
the station is added, otherwise ucode will assert.

Signed-off-by: Mohamed Abbas <mabbas@xxxxxxxxxxxxxxx>
Signed-off-by: Zhu Yi <yi.zhu@xxxxxxxxx>
---
 drivers/net/wireless/iwl-4965-rs.c |   61 +++++++++++++++---------------------
 drivers/net/wireless/iwl-4965.h    |    1 +
 drivers/net/wireless/iwl-base.c    |    1 +
 3 files changed, 27 insertions(+), 36 deletions(-)

diff --git a/drivers/net/wireless/iwl-4965-rs.c b/drivers/net/wireless/iwl-4965-rs.c
index aad244e..6f3d4ab 100644
--- a/drivers/net/wireless/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwl-4965-rs.c
@@ -110,7 +110,6 @@ struct iwl_rate_scale_priv {
 	u8 is_green;
 	u8 is_dup;
 	u8 phymode;
-	u8 ready;
 	u8 ibss_sta_added;
 	u16 active_rate;
 	u16 active_siso_rate;
@@ -183,7 +182,7 @@ static int rs_send_lq_cmd(struct iwl_priv *priv,
 #ifdef CONFIG_IWLWIFI_DEBUG
 	int i;
 #endif
-	int rc = 0;
+	int rc = -1;
 
 	struct iwl_host_cmd cmd = {
 		.id = REPLY_TX_LINK_QUALITY_CMD,
@@ -194,7 +193,7 @@ static int rs_send_lq_cmd(struct iwl_priv *priv,
 
 	if ((lq->sta_id == 0xFF) &&
 	    (priv->iw_mode == IEEE80211_IF_TYPE_IBSS))
-		return -1;
+		return rc;
 
 	if (lq->sta_id == 0xFF)
 		lq->sta_id = IWL_AP_ID;
@@ -212,7 +211,8 @@ static int rs_send_lq_cmd(struct iwl_priv *priv,
 
 	if (flags & CMD_ASYNC)
 		cmd.meta.u.callback = iwl_lq_sync_callback;
-	rc = iwl_send_cmd(priv, &cmd);
+	if (iwl_is_associated(priv) && priv->lq_mngr.lq_ready)
+		rc = iwl_send_cmd(priv, &cmd);
 
 	return rc;
 }
@@ -635,6 +635,9 @@ static void rs_tx_status(void *priv_rate,
 
 	lq = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv;
 
+	if (!priv->lq_mngr.lq_ready)
+		return;
+
 	if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) && !lq->ibss_sta_added)
 		return;
 
@@ -1374,11 +1377,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 	if (!sta || !sta->rate_ctrl_priv)
 		return;
 
-	lq_data = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv;
-	if (!lq_data->ready) {
+	if (!priv->lq_mngr.lq_ready) {
 		IWL_DEBUG_RATE("still rate scaling not ready\n");
 		return;
 	}
+	lq_data = (struct iwl_rate_scale_priv *)sta->rate_ctrl_priv;
 
 	if (!lq_data->search_better_tbl)
 		active_tbl = lq_data->active_tbl;
@@ -1449,6 +1452,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 					   &(lq_data->lq), sta);
 			if (!rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC))
 				lq_data->commit_lq = 0;
+			else
+				lq_data->commit_lq = 1;
 		}
 		goto out;
 
@@ -1577,6 +1582,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 		rs_fill_link_cmd(lq_data, &mcs_rate, &(lq_data->lq), sta);
 		if (!rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC))
 			lq_data->commit_lq = 0;
+		else
+			lq_data->commit_lq = 1;
 	}
 	rs_stay_in_table(lq_data);
 	if (!update_lq
@@ -1603,6 +1610,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 					   &(lq_data->lq), sta);
 			if (!rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC))
 				lq_data->commit_lq = 0;
+			else
+				lq_data->commit_lq = 1;
 		}
 		tbl1 = &(lq_data->lq_info[lq_data->active_tbl]);
 		if (is_legacy(tbl1->lq_type) &&
@@ -1650,8 +1659,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
 
 
 static void rs_initialize_lq(struct iwl_priv *priv,
-			     struct sta_info *sta,
-			     int flg)
+			     struct sta_info *sta)
 {
 	int i;
 	struct iwl_rate_scale_priv *lq;
@@ -1769,18 +1777,18 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
 			lq->lq.sta_id = sta_id;
 			lq->lq.rate_scale_table[0].rate_n_flags = 0;
 			lq->ibss_sta_added = 1;
-			lq->ready = 1;
 			lq->commit_lq = 1;
-			rs_initialize_lq(priv, sta, CMD_ASYNC);
+			rs_initialize_lq(priv, sta);
 		}
 		if (!lq->ibss_sta_added)
 			goto done;
 	}
 
 
-	if (lq->commit_lq && lq->ready) {
+	if (lq->commit_lq) {
 		lq->commit_lq = 0;
-		rs_send_lq_cmd(priv, &lq->lq, CMD_ASYNC);
+		if (rs_send_lq_cmd(priv, &lq->lq, CMD_ASYNC))
+			lq->commit_lq = 1;
 	}
 
  done:
@@ -1855,7 +1863,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
 			crl->lq.sta_id = sta_id;
 			crl->lq.rate_scale_table[0].rate_n_flags = 0;
 		}
-		crl->ready = 1;
+		priv->lq_mngr.lq_ready = 1;
 	}
 
 	for (i = 0; i < mode->num_rates; i++) {
@@ -1891,13 +1899,8 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
 	crl->active_mimo_rate = crl->active_mimo_rate << IWL_FIRST_OFDM_RATE;
 #endif /*CONFIG_IWLWIFI_HT*/
 
-	if (priv && (priv->iw_mode != IEEE80211_IF_TYPE_IBSS)) {
-		mutex_lock(&priv->mutex);
-		rs_initialize_lq(priv, sta, 0);
-		mutex_unlock(&priv->mutex);
-	} else
-		rs_initialize_lq(priv, sta, CMD_ASYNC);
-
+	if (priv)
+		rs_initialize_lq(priv, sta);
 }
 
 static int rs_fill_link_cmd(struct iwl_rate_scale_priv *lq_data,
@@ -2012,6 +2015,7 @@ static void rs_clear(void *priv_rate)
 
 	IWL_DEBUG_RATE("NOP\n");
 
+	priv->lq_mngr.lq_ready = 0;
 #ifdef CONFIG_IWLWIFI_HT
 #ifdef CONFIG_IWLWIFI_HT_AGG
 	if (priv->lq_mngr.agg_ctrl.granted_ba)
@@ -2133,24 +2137,9 @@ int iwl_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
 
 void iwl_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
 {
-	struct ieee80211_local *local = hw_to_local(hw);
 	struct iwl_priv *priv = hw->priv;
-	struct iwl_rate_scale_priv *rs_priv;
-	struct sta_info *sta;
 
-	sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr);
-	if (!sta || !sta->rate_ctrl_priv) {
-		if (sta) {
-			sta_info_put(sta);
-			IWL_DEBUG_RATE("leave - no private rate data!\n");
-		} else
-			IWL_DEBUG_RATE("leave - no station!\n");
-		return;
-	}
-
-	rs_priv = (void *)sta->rate_ctrl_priv;
-	rs_priv->ready = 1;
-	sta_info_put(sta);
+	priv->lq_mngr.lq_ready = 1;
 }
 
 void iwl_rate_control_register(void)
diff --git a/drivers/net/wireless/iwl-4965.h b/drivers/net/wireless/iwl-4965.h
index 9e4a663..8665929 100644
--- a/drivers/net/wireless/iwl-4965.h
+++ b/drivers/net/wireless/iwl-4965.h
@@ -196,6 +196,7 @@ struct iwl_lq_mngr {
 	unsigned long stamp_last;
 	u32 flush_time;
 	u32 tx_packets;
+	u8 lq_ready;
 };
 
 
diff --git a/drivers/net/wireless/iwl-base.c b/drivers/net/wireless/iwl-base.c
index 87ad5d8..57b8195 100644
--- a/drivers/net/wireless/iwl-base.c
+++ b/drivers/net/wireless/iwl-base.c
@@ -7878,6 +7878,7 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
 	IWL_DEBUG_MAC80211("enter\n");
 
 #if IWL == 4965
+	priv->lq_mngr.lq_ready = 0;
 #ifdef CONFIG_IWLWIFI_HT
 	spin_lock_irqsave(&priv->lock, flags);
 	memset(&priv->current_assoc_ht, 0, sizeof(struct sta_ht_info));
-- 
1.5.2
-
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux