aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
diff options
context:
space:
mode:
authorMohamed Abbas <mabbas@linux.intel.com>2007-11-11 22:37:42 -0500
committerJohn W. Linville <linville@tuxdriver.com>2007-11-14 21:16:46 -0500
commit14577f239fe5193d556ef1471c8667dabd556418 (patch)
tree1b6c69370bcb0f3b83d492c304471e7d80a921c0 /drivers/net/wireless/iwlwifi/iwl-3945-rs.c
parenta0af5f14542a2e0687f95e093a33ea7301fe8cc5 (diff)
iwl3945: place CCK rates in front of OFDM for supported rates
The patch fixes association failure (reason = 18) bug by arranging CCK rates before OFDM rates. This patch will register with mac80211 the modified rate arrangement with CCK rate first. Change rate scale algorithm also to deal with rate change. Fix Txpower and rate Table commands to be constructed correctly after rearrangement. Signed-off-by: Mohamed Abbas <mabbas@linux.intel.com> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945-rs.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c56
1 files changed, 48 insertions, 8 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 262ab0b55824..c48b1b537d2b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -71,19 +71,19 @@ struct iwl_rate_scale_priv {
71}; 71};
72 72
73static s32 iwl_expected_tpt_g[IWL_RATE_COUNT] = { 73static s32 iwl_expected_tpt_g[IWL_RATE_COUNT] = {
74 0, 0, 76, 104, 130, 168, 191, 202, 7, 13, 35, 58 74 7, 13, 35, 58, 0, 0, 76, 104, 130, 168, 191, 202
75}; 75};
76 76
77static s32 iwl_expected_tpt_g_prot[IWL_RATE_COUNT] = { 77static s32 iwl_expected_tpt_g_prot[IWL_RATE_COUNT] = {
78 0, 0, 0, 80, 93, 113, 123, 125, 7, 13, 35, 58 78 7, 13, 35, 58, 0, 0, 0, 80, 93, 113, 123, 125
79}; 79};
80 80
81static s32 iwl_expected_tpt_a[IWL_RATE_COUNT] = { 81static s32 iwl_expected_tpt_a[IWL_RATE_COUNT] = {
82 40, 57, 72, 98, 121, 154, 177, 186, 0, 0, 0, 0 82 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186
83}; 83};
84 84
85static s32 iwl_expected_tpt_b[IWL_RATE_COUNT] = { 85static s32 iwl_expected_tpt_b[IWL_RATE_COUNT] = {
86 0, 0, 0, 0, 0, 0, 0, 0, 7, 13, 35, 58 86 7, 13, 35, 58, 0, 0, 0, 0, 0, 0, 0, 0
87}; 87};
88 88
89struct iwl_tpt_entry { 89struct iwl_tpt_entry {
@@ -350,6 +350,10 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
350 350
351 sta->last_txrate = sta->txrate; 351 sta->last_txrate = sta->txrate;
352 352
353 /* For MODE_IEEE80211A mode it start at IWL_FIRST_OFDM_RATE */
354 if (local->hw.conf.phymode == MODE_IEEE80211A)
355 sta->last_txrate += IWL_FIRST_OFDM_RATE;
356
353 IWL_DEBUG_RATE("leave\n"); 357 IWL_DEBUG_RATE("leave\n");
354} 358}
355 359
@@ -417,6 +421,33 @@ static void rs_free_sta(void *priv, void *priv_sta)
417 IWL_DEBUG_RATE("leave\n"); 421 IWL_DEBUG_RATE("leave\n");
418} 422}
419 423
424
425/*
426 * get ieee prev rate from rate scale table.
427 * for A and B mode we need to overright prev
428 * value
429 */
430static int rs_adjust_next_rate(struct iwl_priv *priv, int rate)
431{
432 int next_rate = iwl_get_prev_ieee_rate(rate);
433
434 switch (priv->phymode) {
435 case MODE_IEEE80211A:
436 if (rate == IWL_RATE_12M_INDEX)
437 next_rate = IWL_RATE_9M_INDEX;
438 else if (rate == IWL_RATE_6M_INDEX)
439 next_rate = IWL_RATE_6M_INDEX;
440 break;
441 case MODE_IEEE80211B:
442 if (rate == IWL_RATE_11M_INDEX_TABLE)
443 next_rate = IWL_RATE_5M_INDEX_TABLE;
444 break;
445 default:
446 break;
447 }
448
449 return next_rate;
450}
420/** 451/**
421 * rs_tx_status - Update rate control values based on Tx results 452 * rs_tx_status - Update rate control values based on Tx results
422 * 453 *
@@ -479,7 +510,8 @@ static void rs_tx_status(void *priv_rate,
479 last_index = scale_rate_index; 510 last_index = scale_rate_index;
480 } else { 511 } else {
481 current_count = priv->retry_rate; 512 current_count = priv->retry_rate;
482 last_index = iwl_get_prev_ieee_rate(scale_rate_index); 513 last_index = rs_adjust_next_rate(priv,
514 scale_rate_index);
483 } 515 }
484 516
485 /* Update this rate accounting for as many retries 517 /* Update this rate accounting for as many retries
@@ -494,9 +526,10 @@ static void rs_tx_status(void *priv_rate,
494 526
495 if (retries) 527 if (retries)
496 scale_rate_index = 528 scale_rate_index =
497 iwl_get_prev_ieee_rate(scale_rate_index); 529 rs_adjust_next_rate(priv, scale_rate_index);
498 } 530 }
499 531
532
500 /* Update the last index window with success/failure based on ACK */ 533 /* Update the last index window with success/failure based on ACK */
501 IWL_DEBUG_RATE("Update rate %d with %s.\n", 534 IWL_DEBUG_RATE("Update rate %d with %s.\n",
502 last_index, 535 last_index,
@@ -672,7 +705,10 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
672 } 705 }
673 706
674 rate_mask = sta->supp_rates; 707 rate_mask = sta->supp_rates;
675 index = min(sta->txrate & 0xffff, IWL_RATE_COUNT - 1); 708 index = min(sta->last_txrate & 0xffff, IWL_RATE_COUNT - 1);
709
710 if (priv->phymode == (u8) MODE_IEEE80211A)
711 rate_mask = rate_mask << IWL_FIRST_OFDM_RATE;
676 712
677 rs_priv = (void *)sta->rate_ctrl_priv; 713 rs_priv = (void *)sta->rate_ctrl_priv;
678 714
@@ -801,7 +837,11 @@ static struct ieee80211_rate *rs_get_rate(void *priv_rate,
801 out: 837 out:
802 838
803 sta->last_txrate = index; 839 sta->last_txrate = index;
804 sta->txrate = sta->last_txrate; 840 if (priv->phymode == (u8) MODE_IEEE80211A)
841 sta->txrate = sta->last_txrate - IWL_FIRST_OFDM_RATE;
842 else
843 sta->txrate = sta->last_txrate;
844
805 sta_info_put(sta); 845 sta_info_put(sta);
806 846
807 IWL_DEBUG_RATE("leave: %d\n", index); 847 IWL_DEBUG_RATE("leave: %d\n", index);