iwl3945: Fix rate scale for B-mode connection

This patch make sure we use only CCK rate for B only network.
For 3945 driver, it sets REPLY_RATE_SCALE command every time
we connect to a new network. In this command we set for every
rate the number of try and next rate. The problem mac80211 reports
same mode for both B and G mode as IEEE80211_BAND_2GHZ which will cause
using invalid rate other than CCK in B only network. THis patch
on association will examine sta valid rate on association, if no
OFDM rate in valid available rates it considers it as B only mode so
we can set REPLY_RATE_SCALE command with valid B only network and only
choose CCK rate in rate scaling.

Signed-off-by: Mohamed Abbas <mohamed.abbas@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 4e6b715..4e9e592 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -277,12 +277,14 @@
 		else if (rate == IWL_RATE_6M_INDEX)
 			next_rate = IWL_RATE_6M_INDEX;
 		break;
-/* XXX cannot be invoked in current mac80211 so not a regression
-	case MODE_IEEE80211B:
-		if (rate == IWL_RATE_11M_INDEX_TABLE)
-			next_rate = IWL_RATE_5M_INDEX_TABLE;
+	case IEEE80211_BAND_2GHZ:
+		if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
+		    iwl3945_is_associated(priv)) {
+			if (rate == IWL_RATE_11M_INDEX)
+				next_rate = IWL_RATE_5M_INDEX;
+		}
 		break;
- */
+
 	default:
 		break;
 	}
@@ -2378,7 +2380,8 @@
 			iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0);
 		table[index].try_cnt = priv->retry_rate;
 		prev_index = iwl3945_get_prev_ieee_rate(i);
-		table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index;
+		table[index].next_rate_index =
+				iwl3945_rates[prev_index].table_rs_index;
 	}
 
 	switch (priv->band) {
@@ -2386,11 +2389,14 @@
 		IWL_DEBUG_RATE("Select A mode rate scale\n");
 		/* If one of the following CCK rates is used,
 		 * have it fall back to the 6M OFDM rate */
-		for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++)
-			table[i].next_rate_index = iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
+		for (i = IWL_RATE_1M_INDEX_TABLE;
+			i <= IWL_RATE_11M_INDEX_TABLE; i++)
+			table[i].next_rate_index =
+			  iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
 
 		/* Don't fall back to CCK rates */
-		table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = IWL_RATE_9M_INDEX_TABLE;
+		table[IWL_RATE_12M_INDEX_TABLE].next_rate_index =
+						IWL_RATE_9M_INDEX_TABLE;
 
 		/* Don't drop out of OFDM rates */
 		table[IWL_RATE_6M_INDEX_TABLE].next_rate_index =
@@ -2401,11 +2407,20 @@
 		IWL_DEBUG_RATE("Select B/G mode rate scale\n");
 		/* If an OFDM rate is used, have it fall back to the
 		 * 1M CCK rates */
-		for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++)
-			table[i].next_rate_index = iwl3945_rates[IWL_FIRST_CCK_RATE].table_rs_index;
 
-		/* CCK shouldn't fall back to OFDM... */
-		table[IWL_RATE_11M_INDEX_TABLE].next_rate_index = IWL_RATE_5M_INDEX_TABLE;
+		if (!(priv->sta_supp_rates & IWL_OFDM_RATES_MASK) &&
+		    iwl3945_is_associated(priv)) {
+
+			index = IWL_FIRST_CCK_RATE;
+			for (i = IWL_RATE_6M_INDEX_TABLE;
+			     i <= IWL_RATE_54M_INDEX_TABLE; i++)
+				table[i].next_rate_index =
+					iwl3945_rates[index].table_rs_index;
+
+			index = IWL_RATE_11M_INDEX_TABLE;
+			/* CCK shouldn't fall back to OFDM... */
+			table[index].next_rate_index = IWL_RATE_5M_INDEX_TABLE;
+		}
 		break;
 
 	default: