aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
diff options
context:
space:
mode:
authorBen Cahill <ben.m.cahill@intel.com>2007-11-28 22:09:44 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:05:15 -0500
commit7762635547ad31ecb045e7073989e76ae13e6c54 (patch)
tree041e42e31702b2a0e9934baf7c395aa0c314fb63 /drivers/net/wireless/iwlwifi/iwl-4965-rs.c
parentf58177b9c3f377eee31bac719bda87e1aab415ab (diff)
iwl4965: add comments to rate scaling code
Add comments to rate scaling code. Signed-off-by: Ben Cahill <ben.m.cahill@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-4965-rs.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.c467
1 files changed, 409 insertions, 58 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 8d3d9f72a8ce..218c5a355ddb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -47,13 +47,12 @@
47#define IWL_NUMBER_TRY 1 47#define IWL_NUMBER_TRY 1
48#define IWL_HT_NUMBER_TRY 3 48#define IWL_HT_NUMBER_TRY 3
49 49
50#define IWL_RATE_MAX_WINDOW 62 50#define IWL_RATE_MAX_WINDOW 62 /* # tx in history window */
51#define IWL_RATE_HIGH_TH 10880 51#define IWL_RATE_MIN_FAILURE_TH 6 /* min failures to calc tpt */
52#define IWL_RATE_MIN_FAILURE_TH 6 52#define IWL_RATE_MIN_SUCCESS_TH 8 /* min successes to calc tpt */
53#define IWL_RATE_MIN_SUCCESS_TH 8 53
54#define IWL_RATE_DECREASE_TH 1920 54/* max time to accum history 2 seconds */
55#define IWL_RATE_INCREASE_TH 8960 55#define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ)
56#define IWL_RATE_SCALE_FLUSH_INTVL (2*HZ) /*2 seconds */
57 56
58static u8 rs_ht_to_legacy[] = { 57static u8 rs_ht_to_legacy[] = {
59 IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX, 58 IWL_RATE_6M_INDEX, IWL_RATE_6M_INDEX,
@@ -69,54 +68,74 @@ struct iwl4965_rate {
69 u32 rate_n_flags; 68 u32 rate_n_flags;
70} __attribute__ ((packed)); 69} __attribute__ ((packed));
71 70
71/**
72 * struct iwl4965_rate_scale_data -- tx success history for one rate
73 */
72struct iwl4965_rate_scale_data { 74struct iwl4965_rate_scale_data {
73 u64 data; 75 u64 data; /* bitmap of successful frames */
74 s32 success_counter; 76 s32 success_counter; /* number of frames successful */
75 s32 success_ratio; 77 s32 success_ratio; /* per-cent * 128 */
76 s32 counter; 78 s32 counter; /* number of frames attempted */
77 s32 average_tpt; 79 s32 average_tpt; /* success ratio * expected throughput */
78 unsigned long stamp; 80 unsigned long stamp;
79}; 81};
80 82
83/**
84 * struct iwl4965_scale_tbl_info -- tx params and success history for all rates
85 *
86 * There are two of these in struct iwl_rate_scale_priv,
87 * one for "active", and one for "search".
88 */
81struct iwl4965_scale_tbl_info { 89struct iwl4965_scale_tbl_info {
82 enum iwl4965_table_type lq_type; 90 enum iwl4965_table_type lq_type;
83 enum iwl4965_antenna_type antenna_type; 91 enum iwl4965_antenna_type antenna_type;
84 u8 is_SGI; 92 u8 is_SGI; /* 1 = short guard interval */
85 u8 is_fat; 93 u8 is_fat; /* 1 = 40 MHz channel width */
86 u8 is_dup; 94 u8 is_dup; /* 1 = duplicated data streams */
87 u8 action; 95 u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
88 s32 *expected_tpt; 96 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
89 struct iwl4965_rate current_rate; 97 struct iwl4965_rate current_rate; /* rate_n_flags, uCode API format */
90 struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; 98 struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
91}; 99};
92 100
101/**
102 * struct iwl_rate_scale_priv -- driver's rate scaling private structure
103 *
104 * Pointer to this gets passed back and forth between driver and mac80211.
105 */
93struct iwl4965_rate_scale_priv { 106struct iwl4965_rate_scale_priv {
94 u8 active_tbl; 107 u8 active_tbl; /* index of active table, range 0-1 */
95 u8 enable_counter; 108 u8 enable_counter; /* indicates HT mode */
96 u8 stay_in_tbl; 109 u8 stay_in_tbl; /* 1: disallow, 0: allow search for new mode */
97 u8 search_better_tbl; 110 u8 search_better_tbl; /* 1: currently trying alternate mode */
98 s32 last_tpt; 111 s32 last_tpt;
112
113 /* The following determine when to search for a new mode */
99 u32 table_count_limit; 114 u32 table_count_limit;
100 u32 max_failure_limit; 115 u32 max_failure_limit; /* # failed frames before new search */
101 u32 max_success_limit; 116 u32 max_success_limit; /* # successful frames before new search */
102 u32 table_count; 117 u32 table_count;
103 u32 total_failed; 118 u32 total_failed; /* total failed frames, any/all rates */
104 u32 total_success; 119 u32 total_success; /* total successful frames, any/all rates */
105 u32 flush_timer; 120 u32 flush_timer; /* time staying in mode before new search */
106 u8 action_counter; 121
122 u8 action_counter; /* # mode-switch actions tried */
107 u8 antenna; 123 u8 antenna;
108 u8 valid_antenna; 124 u8 valid_antenna;
109 u8 is_green; 125 u8 is_green;
110 u8 is_dup; 126 u8 is_dup;
111 u8 phymode; 127 u8 phymode;
112 u8 ibss_sta_added; 128 u8 ibss_sta_added;
129
130 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
113 u32 supp_rates; 131 u32 supp_rates;
114 u16 active_rate; 132 u16 active_rate;
115 u16 active_siso_rate; 133 u16 active_siso_rate;
116 u16 active_mimo_rate; 134 u16 active_mimo_rate;
117 u16 active_rate_basic; 135 u16 active_rate_basic;
136
118 struct iwl4965_link_quality_cmd lq; 137 struct iwl4965_link_quality_cmd lq;
119 struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; 138 struct iwl4965_scale_tbl_info lq_info[LQ_SIZE]; /* "active", "search" */
120#ifdef CONFIG_MAC80211_DEBUGFS 139#ifdef CONFIG_MAC80211_DEBUGFS
121 struct dentry *rs_sta_dbgfs_scale_table_file; 140 struct dentry *rs_sta_dbgfs_scale_table_file;
122 struct dentry *rs_sta_dbgfs_stats_table_file; 141 struct dentry *rs_sta_dbgfs_stats_table_file;
@@ -142,6 +161,12 @@ static void rs_dbgfs_set_mcs(struct iwl4965_rate_scale_priv *rs_priv,
142 struct iwl4965_rate *mcs, int index) 161 struct iwl4965_rate *mcs, int index)
143{} 162{}
144#endif 163#endif
164
165/*
166 * Expected throughput metrics for following rates:
167 * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits
168 * "G" is the only table that supports CCK (the first 4 rates).
169 */
145static s32 expected_tpt_A[IWL_RATE_COUNT] = { 170static s32 expected_tpt_A[IWL_RATE_COUNT] = {
146 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186 171 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186
147}; 172};
@@ -244,6 +269,13 @@ static void rs_rate_scale_clear_window(struct iwl4965_rate_scale_data *window)
244 window->stamp = 0; 269 window->stamp = 0;
245} 270}
246 271
272/**
273 * rs_collect_tx_data - Update the success/failure sliding window
274 *
275 * We keep a sliding window of the last 62 packets transmitted
276 * at this rate. window->data contains the bitmask of successful
277 * packets.
278 */
247static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows, 279static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
248 int scale_index, s32 tpt, u32 status) 280 int scale_index, s32 tpt, u32 status)
249{ 281{
@@ -255,10 +287,18 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
255 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) 287 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
256 return -EINVAL; 288 return -EINVAL;
257 289
290 /* Select data for current tx bit rate */
258 window = &(windows[scale_index]); 291 window = &(windows[scale_index]);
259 292
293 /*
294 * Keep track of only the latest 62 tx frame attempts in this rate's
295 * history window; anything older isn't really relevant any more.
296 * If we have filled up the sliding window, drop the oldest attempt;
297 * if the oldest attempt (highest bit in bitmap) shows "success",
298 * subtract "1" from the success counter (this is the main reason
299 * we keep these bitmaps!).
300 */
260 if (window->counter >= win_size) { 301 if (window->counter >= win_size) {
261
262 window->counter = win_size - 1; 302 window->counter = win_size - 1;
263 mask = 1; 303 mask = 1;
264 mask = (mask << (win_size - 1)); 304 mask = (mask << (win_size - 1));
@@ -268,7 +308,11 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
268 } 308 }
269 } 309 }
270 310
311 /* Increment frames-attempted counter */
271 window->counter = window->counter + 1; 312 window->counter = window->counter + 1;
313
314 /* Shift bitmap by one frame (throw away oldest history),
315 * OR in "1", and increment "success" if this frame was successful. */
272 mask = window->data; 316 mask = window->data;
273 window->data = (mask << 1); 317 window->data = (mask << 1);
274 if (status != 0) { 318 if (status != 0) {
@@ -276,6 +320,7 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
276 window->data |= 0x1; 320 window->data |= 0x1;
277 } 321 }
278 322
323 /* Calculate current success ratio, avoid divide-by-0! */
279 if (window->counter > 0) 324 if (window->counter > 0)
280 window->success_ratio = 128 * (100 * window->success_counter) 325 window->success_ratio = 128 * (100 * window->success_counter)
281 / window->counter; 326 / window->counter;
@@ -284,17 +329,22 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
284 329
285 fail_count = window->counter - window->success_counter; 330 fail_count = window->counter - window->success_counter;
286 331
332 /* Calculate average throughput, if we have enough history. */
287 if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) || 333 if ((fail_count >= IWL_RATE_MIN_FAILURE_TH) ||
288 (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH)) 334 (window->success_counter >= IWL_RATE_MIN_SUCCESS_TH))
289 window->average_tpt = (window->success_ratio * tpt + 64) / 128; 335 window->average_tpt = (window->success_ratio * tpt + 64) / 128;
290 else 336 else
291 window->average_tpt = IWL_INVALID_VALUE; 337 window->average_tpt = IWL_INVALID_VALUE;
292 338
339 /* Tag this window as having been updated */
293 window->stamp = jiffies; 340 window->stamp = jiffies;
294 341
295 return 0; 342 return 0;
296} 343}
297 344
345/*
346 * Fill uCode API rate_n_flags field, based on "search" or "active" table.
347 */
298static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate, 348static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate,
299 struct iwl4965_scale_tbl_info *tbl, 349 struct iwl4965_scale_tbl_info *tbl,
300 int index, u8 use_green) 350 int index, u8 use_green)
@@ -349,6 +399,10 @@ static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate,
349 } 399 }
350} 400}
351 401
402/*
403 * Interpret uCode API's rate_n_flags format,
404 * fill "search" or "active" tx mode table.
405 */
352static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, 406static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
353 int phymode, struct iwl4965_scale_tbl_info *tbl, 407 int phymode, struct iwl4965_scale_tbl_info *tbl,
354 int *rate_idx) 408 int *rate_idx)
@@ -362,11 +416,12 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
362 *rate_idx = -1; 416 *rate_idx = -1;
363 return -EINVAL; 417 return -EINVAL;
364 } 418 }
365 tbl->is_SGI = 0; 419 tbl->is_SGI = 0; /* default legacy setup */
366 tbl->is_fat = 0; 420 tbl->is_fat = 0;
367 tbl->is_dup = 0; 421 tbl->is_dup = 0;
368 tbl->antenna_type = ANT_BOTH; 422 tbl->antenna_type = ANT_BOTH; /* default MIMO setup */
369 423
424 /* legacy rate format */
370 if (!(mcs_rate->rate_n_flags & RATE_MCS_HT_MSK)) { 425 if (!(mcs_rate->rate_n_flags & RATE_MCS_HT_MSK)) {
371 ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_AB_MSK); 426 ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_AB_MSK);
372 427
@@ -386,6 +441,7 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
386 } 441 }
387 *rate_idx = index; 442 *rate_idx = index;
388 443
444 /* HT rate format, SISO (might be 20 MHz legacy or 40 MHz fat width) */
389 } else if (iwl4965_rate_get_rate(mcs_rate->rate_n_flags) 445 } else if (iwl4965_rate_get_rate(mcs_rate->rate_n_flags)
390 <= IWL_RATE_SISO_60M_PLCP) { 446 <= IWL_RATE_SISO_60M_PLCP) {
391 tbl->lq_type = LQ_SISO; 447 tbl->lq_type = LQ_SISO;
@@ -410,6 +466,8 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
410 tbl->is_dup = 1; 466 tbl->is_dup = 1;
411 467
412 *rate_idx = index; 468 *rate_idx = index;
469
470 /* HT rate format, MIMO (might be 20 MHz legacy or 40 MHz fat width) */
413 } else { 471 } else {
414 tbl->lq_type = LQ_MIMO; 472 tbl->lq_type = LQ_MIMO;
415 if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK) 473 if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK)
@@ -564,8 +622,9 @@ static void rs_get_lower_rate(struct iwl4965_rate_scale_priv *lq_data,
564 622
565 rs_get_supported_rates(lq_data, NULL, tbl->lq_type, &rate_mask); 623 rs_get_supported_rates(lq_data, NULL, tbl->lq_type, &rate_mask);
566 624
567 /* mask with station rate restriction */ 625 /* Mask with station rate restriction */
568 if (is_legacy(tbl->lq_type)) { 626 if (is_legacy(tbl->lq_type)) {
627 /* supp_rates has no CCK bits in A mode */
569 if (lq_data->phymode == (u8) MODE_IEEE80211A) 628 if (lq_data->phymode == (u8) MODE_IEEE80211A)
570 rate_mask = (u16)(rate_mask & 629 rate_mask = (u16)(rate_mask &
571 (lq_data->supp_rates << IWL_FIRST_OFDM_RATE)); 630 (lq_data->supp_rates << IWL_FIRST_OFDM_RATE));
@@ -573,7 +632,7 @@ static void rs_get_lower_rate(struct iwl4965_rate_scale_priv *lq_data,
573 rate_mask = (u16)(rate_mask & lq_data->supp_rates); 632 rate_mask = (u16)(rate_mask & lq_data->supp_rates);
574 } 633 }
575 634
576 /* if we did switched from HT to legacy check current rate */ 635 /* If we switched from HT to legacy, check current rate */
577 if (switch_to_legacy && (rate_mask & (1 << scale_index))) { 636 if (switch_to_legacy && (rate_mask & (1 << scale_index))) {
578 rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green); 637 rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green);
579 return; 638 return;
@@ -588,6 +647,9 @@ static void rs_get_lower_rate(struct iwl4965_rate_scale_priv *lq_data,
588 rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green); 647 rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green);
589} 648}
590 649
650/*
651 * mac80211 sends us Tx status
652 */
591static void rs_tx_status(void *priv_rate, 653static void rs_tx_status(void *priv_rate,
592 struct net_device *dev, 654 struct net_device *dev,
593 struct sk_buff *skb, 655 struct sk_buff *skb,
@@ -641,11 +703,14 @@ static void rs_tx_status(void *priv_rate,
641 table = &lq->lq; 703 table = &lq->lq;
642 active_index = lq->active_tbl; 704 active_index = lq->active_tbl;
643 705
706 /* Get mac80211 antenna info */
644 lq->antenna = (lq->valid_antenna & local->hw.conf.antenna_sel_tx); 707 lq->antenna = (lq->valid_antenna & local->hw.conf.antenna_sel_tx);
645 if (!lq->antenna) 708 if (!lq->antenna)
646 lq->antenna = lq->valid_antenna; 709 lq->antenna = lq->valid_antenna;
647 710
711 /* Ignore mac80211 antenna info for now */
648 lq->antenna = lq->valid_antenna; 712 lq->antenna = lq->valid_antenna;
713
649 curr_tbl = &(lq->lq_info[active_index]); 714 curr_tbl = &(lq->lq_info[active_index]);
650 search_tbl = &(lq->lq_info[(1 - active_index)]); 715 search_tbl = &(lq->lq_info[(1 - active_index)]);
651 window = (struct iwl4965_rate_scale_data *) 716 window = (struct iwl4965_rate_scale_data *)
@@ -664,6 +729,14 @@ static void rs_tx_status(void *priv_rate,
664 return; 729 return;
665 } 730 }
666 731
732 /*
733 * Ignore this Tx frame response if its initial rate doesn't match
734 * that of latest Link Quality command. There may be stragglers
735 * from a previous Link Quality command, but we're no longer interested
736 * in those; they're either from the "active" mode while we're trying
737 * to check "search" mode, or a prior "search" mode after we've moved
738 * to a new "search" mode (which might become the new "active" mode).
739 */
667 if (retries && 740 if (retries &&
668 (tx_mcs.rate_n_flags != 741 (tx_mcs.rate_n_flags !=
669 le32_to_cpu(table->rs_table[0].rate_n_flags))) { 742 le32_to_cpu(table->rs_table[0].rate_n_flags))) {
@@ -674,12 +747,17 @@ static void rs_tx_status(void *priv_rate,
674 return; 747 return;
675 } 748 }
676 749
750 /* Update frame history window with "failure" for each Tx retry. */
677 while (retries) { 751 while (retries) {
752 /* Look up the rate and other info used for each tx attempt.
753 * Each tx attempt steps one entry deeper in the rate table. */
678 tx_mcs.rate_n_flags = 754 tx_mcs.rate_n_flags =
679 le32_to_cpu(table->rs_table[index].rate_n_flags); 755 le32_to_cpu(table->rs_table[index].rate_n_flags);
680 rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, 756 rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode,
681 &tbl_type, &rs_index); 757 &tbl_type, &rs_index);
682 758
759 /* If type matches "search" table,
760 * add failure to "search" history */
683 if ((tbl_type.lq_type == search_tbl->lq_type) && 761 if ((tbl_type.lq_type == search_tbl->lq_type) &&
684 (tbl_type.antenna_type == search_tbl->antenna_type) && 762 (tbl_type.antenna_type == search_tbl->antenna_type) &&
685 (tbl_type.is_SGI == search_tbl->is_SGI)) { 763 (tbl_type.is_SGI == search_tbl->is_SGI)) {
@@ -687,8 +765,10 @@ static void rs_tx_status(void *priv_rate,
687 tpt = search_tbl->expected_tpt[rs_index]; 765 tpt = search_tbl->expected_tpt[rs_index];
688 else 766 else
689 tpt = 0; 767 tpt = 0;
690 rs_collect_tx_data(search_win, 768 rs_collect_tx_data(search_win, rs_index, tpt, 0);
691 rs_index, tpt, 0); 769
770 /* Else if type matches "current/active" table,
771 * add failure to "current/active" history */
692 } else if ((tbl_type.lq_type == curr_tbl->lq_type) && 772 } else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
693 (tbl_type.antenna_type == curr_tbl->antenna_type) && 773 (tbl_type.antenna_type == curr_tbl->antenna_type) &&
694 (tbl_type.is_SGI == curr_tbl->is_SGI)) { 774 (tbl_type.is_SGI == curr_tbl->is_SGI)) {
@@ -698,6 +778,9 @@ static void rs_tx_status(void *priv_rate,
698 tpt = 0; 778 tpt = 0;
699 rs_collect_tx_data(window, rs_index, tpt, 0); 779 rs_collect_tx_data(window, rs_index, tpt, 0);
700 } 780 }
781
782 /* If not searching for a new mode, increment failed counter
783 * ... this helps determine when to start searching again */
701 if (lq->stay_in_tbl) 784 if (lq->stay_in_tbl)
702 lq->total_failed++; 785 lq->total_failed++;
703 --retries; 786 --retries;
@@ -705,6 +788,11 @@ static void rs_tx_status(void *priv_rate,
705 788
706 } 789 }
707 790
791 /*
792 * Find (by rate) the history window to update with final Tx attempt;
793 * if Tx was successful first try, use original rate,
794 * else look up the rate that was, finally, successful.
795 */
708 if (!tx_resp->retry_count) 796 if (!tx_resp->retry_count)
709 tx_mcs.rate_n_flags = tx_resp->control.tx_rate; 797 tx_mcs.rate_n_flags = tx_resp->control.tx_rate;
710 else 798 else
@@ -714,11 +802,14 @@ static void rs_tx_status(void *priv_rate,
714 rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode, 802 rs_get_tbl_info_from_mcs(&tx_mcs, priv->phymode,
715 &tbl_type, &rs_index); 803 &tbl_type, &rs_index);
716 804
805 /* Update frame history window with "success" if Tx got ACKed ... */
717 if (tx_resp->flags & IEEE80211_TX_STATUS_ACK) 806 if (tx_resp->flags & IEEE80211_TX_STATUS_ACK)
718 status = 1; 807 status = 1;
719 else 808 else
720 status = 0; 809 status = 0;
721 810
811 /* If type matches "search" table,
812 * add final tx status to "search" history */
722 if ((tbl_type.lq_type == search_tbl->lq_type) && 813 if ((tbl_type.lq_type == search_tbl->lq_type) &&
723 (tbl_type.antenna_type == search_tbl->antenna_type) && 814 (tbl_type.antenna_type == search_tbl->antenna_type) &&
724 (tbl_type.is_SGI == search_tbl->is_SGI)) { 815 (tbl_type.is_SGI == search_tbl->is_SGI)) {
@@ -728,6 +819,9 @@ static void rs_tx_status(void *priv_rate,
728 tpt = 0; 819 tpt = 0;
729 rs_collect_tx_data(search_win, 820 rs_collect_tx_data(search_win,
730 rs_index, tpt, status); 821 rs_index, tpt, status);
822
823 /* Else if type matches "current/active" table,
824 * add final tx status to "current/active" history */
731 } else if ((tbl_type.lq_type == curr_tbl->lq_type) && 825 } else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
732 (tbl_type.antenna_type == curr_tbl->antenna_type) && 826 (tbl_type.antenna_type == curr_tbl->antenna_type) &&
733 (tbl_type.is_SGI == curr_tbl->is_SGI)) { 827 (tbl_type.is_SGI == curr_tbl->is_SGI)) {
@@ -738,6 +832,8 @@ static void rs_tx_status(void *priv_rate,
738 rs_collect_tx_data(window, rs_index, tpt, status); 832 rs_collect_tx_data(window, rs_index, tpt, status);
739 } 833 }
740 834
835 /* If not searching for new mode, increment success/failed counter
836 * ... these help determine when to start searching again */
741 if (lq->stay_in_tbl) { 837 if (lq->stay_in_tbl) {
742 if (status) 838 if (status)
743 lq->total_success++; 839 lq->total_success++;
@@ -745,6 +841,7 @@ static void rs_tx_status(void *priv_rate,
745 lq->total_failed++; 841 lq->total_failed++;
746 } 842 }
747 843
844 /* See if there's a better rate or modulation mode to try. */
748 rs_rate_scale_perform(priv, dev, hdr, sta); 845 rs_rate_scale_perform(priv, dev, hdr, sta);
749 sta_info_put(sta); 846 sta_info_put(sta);
750 return; 847 return;
@@ -774,11 +871,19 @@ static u8 rs_is_other_ant_connected(u8 valid_antenna,
774 return 0; 871 return 0;
775} 872}
776 873
874/*
875 * Begin a period of staying with a selected modulation mode.
876 * Set "stay_in_tbl" flag to prevent any mode switches.
877 * Set frame tx success limits according to legacy vs. high-throughput,
878 * and reset overall (spanning all rates) tx success history statistics.
879 * These control how long we stay using same modulation mode before
880 * searching for a new mode.
881 */
777static void rs_set_stay_in_table(u8 is_legacy, 882static void rs_set_stay_in_table(u8 is_legacy,
778 struct iwl4965_rate_scale_priv *lq_data) 883 struct iwl4965_rate_scale_priv *lq_data)
779{ 884{
780 IWL_DEBUG_HT("we are staying in the same table\n"); 885 IWL_DEBUG_HT("we are staying in the same table\n");
781 lq_data->stay_in_tbl = 1; 886 lq_data->stay_in_tbl = 1; /* only place this gets set */
782 if (is_legacy) { 887 if (is_legacy) {
783 lq_data->table_count_limit = IWL_LEGACY_TABLE_COUNT; 888 lq_data->table_count_limit = IWL_LEGACY_TABLE_COUNT;
784 lq_data->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT; 889 lq_data->max_failure_limit = IWL_LEGACY_FAILURE_LIMIT;
@@ -793,6 +898,9 @@ static void rs_set_stay_in_table(u8 is_legacy,
793 lq_data->total_success = 0; 898 lq_data->total_success = 0;
794} 899}
795 900
901/*
902 * Find correct throughput table for given mode of modulation
903 */
796static void rs_get_expected_tpt_table(struct iwl4965_rate_scale_priv *lq_data, 904static void rs_get_expected_tpt_table(struct iwl4965_rate_scale_priv *lq_data,
797 struct iwl4965_scale_tbl_info *tbl) 905 struct iwl4965_scale_tbl_info *tbl)
798{ 906{
@@ -827,17 +935,33 @@ static void rs_get_expected_tpt_table(struct iwl4965_rate_scale_priv *lq_data,
827} 935}
828 936
829#ifdef CONFIG_IWL4965_HT 937#ifdef CONFIG_IWL4965_HT
938/*
939 * Find starting rate for new "search" high-throughput mode of modulation.
940 * Goal is to find lowest expected rate (under perfect conditions) that is
941 * above the current measured throughput of "active" mode, to give new mode
942 * a fair chance to prove itself without too many challenges.
943 *
944 * This gets called when transitioning to more aggressive modulation
945 * (i.e. legacy to SISO or MIMO, or SISO to MIMO), as well as less aggressive
946 * (i.e. MIMO to SISO). When moving to MIMO, bit rate will typically need
947 * to decrease to match "active" throughput. When moving from MIMO to SISO,
948 * bit rate will typically need to increase, but not if performance was bad.
949 */
830static s32 rs_get_best_rate(struct iwl4965_priv *priv, 950static s32 rs_get_best_rate(struct iwl4965_priv *priv,
831 struct iwl4965_rate_scale_priv *lq_data, 951 struct iwl4965_rate_scale_priv *lq_data,
832 struct iwl4965_scale_tbl_info *tbl, 952 struct iwl4965_scale_tbl_info *tbl, /* "search" */
833 u16 rate_mask, s8 index, s8 rate) 953 u16 rate_mask, s8 index, s8 rate)
834{ 954{
955 /* "active" values */
835 struct iwl4965_scale_tbl_info *active_tbl = 956 struct iwl4965_scale_tbl_info *active_tbl =
836 &(lq_data->lq_info[lq_data->active_tbl]); 957 &(lq_data->lq_info[lq_data->active_tbl]);
837 s32 new_rate, high, low, start_hi;
838 s32 active_sr = active_tbl->win[index].success_ratio; 958 s32 active_sr = active_tbl->win[index].success_ratio;
839 s32 *tpt_tbl = tbl->expected_tpt;
840 s32 active_tpt = active_tbl->expected_tpt[index]; 959 s32 active_tpt = active_tbl->expected_tpt[index];
960
961 /* expected "search" throughput */
962 s32 *tpt_tbl = tbl->expected_tpt;
963
964 s32 new_rate, high, low, start_hi;
841 u16 high_low; 965 u16 high_low;
842 966
843 new_rate = high = low = start_hi = IWL_RATE_INVALID; 967 new_rate = high = low = start_hi = IWL_RATE_INVALID;
@@ -848,6 +972,21 @@ static s32 rs_get_best_rate(struct iwl4965_priv *priv,
848 low = high_low & 0xff; 972 low = high_low & 0xff;
849 high = (high_low >> 8) & 0xff; 973 high = (high_low >> 8) & 0xff;
850 974
975 /*
976 * Lower the "search" bit rate, to give new "search" mode
977 * approximately the same throughput as "active" if:
978 *
979 * 1) "Active" mode has been working modestly well (but not
980 * great), and expected "search" throughput (under perfect
981 * conditions) at candidate rate is above the actual
982 * measured "active" throughput (but less than expected
983 * "active" throughput under perfect conditions).
984 * OR
985 * 2) "Active" mode has been working perfectly or very well
986 * and expected "search" throughput (under perfect
987 * conditions) at candidate rate is above expected
988 * "active" throughput (under perfect conditions).
989 */
851 if ((((100 * tpt_tbl[rate]) > lq_data->last_tpt) && 990 if ((((100 * tpt_tbl[rate]) > lq_data->last_tpt) &&
852 ((active_sr > IWL_RATE_DECREASE_TH) && 991 ((active_sr > IWL_RATE_DECREASE_TH) &&
853 (active_sr <= IWL_RATE_HIGH_TH) && 992 (active_sr <= IWL_RATE_HIGH_TH) &&
@@ -855,21 +994,38 @@ static s32 rs_get_best_rate(struct iwl4965_priv *priv,
855 ((active_sr >= IWL_RATE_SCALE_SWITCH) && 994 ((active_sr >= IWL_RATE_SCALE_SWITCH) &&
856 (tpt_tbl[rate] > active_tpt))) { 995 (tpt_tbl[rate] > active_tpt))) {
857 996
997 /* (2nd or later pass)
998 * If we've already tried to raise the rate, and are
999 * now trying to lower it, use the higher rate. */
858 if (start_hi != IWL_RATE_INVALID) { 1000 if (start_hi != IWL_RATE_INVALID) {
859 new_rate = start_hi; 1001 new_rate = start_hi;
860 break; 1002 break;
861 } 1003 }
1004
862 new_rate = rate; 1005 new_rate = rate;
1006
1007 /* Loop again with lower rate */
863 if (low != IWL_RATE_INVALID) 1008 if (low != IWL_RATE_INVALID)
864 rate = low; 1009 rate = low;
1010
1011 /* Lower rate not available, use the original */
865 else 1012 else
866 break; 1013 break;
1014
1015 /* Else try to raise the "search" rate to match "active" */
867 } else { 1016 } else {
1017 /* (2nd or later pass)
1018 * If we've already tried to lower the rate, and are
1019 * now trying to raise it, use the lower rate. */
868 if (new_rate != IWL_RATE_INVALID) 1020 if (new_rate != IWL_RATE_INVALID)
869 break; 1021 break;
1022
1023 /* Loop again with higher rate */
870 else if (high != IWL_RATE_INVALID) { 1024 else if (high != IWL_RATE_INVALID) {
871 start_hi = high; 1025 start_hi = high;
872 rate = high; 1026 rate = high;
1027
1028 /* Higher rate not available, use the original */
873 } else { 1029 } else {
874 new_rate = rate; 1030 new_rate = rate;
875 break; 1031 break;
@@ -886,6 +1042,9 @@ static inline u8 rs_is_both_ant_supp(u8 valid_antenna)
886 return (rs_is_ant_connected(valid_antenna, ANT_BOTH)); 1042 return (rs_is_ant_connected(valid_antenna, ANT_BOTH));
887} 1043}
888 1044
1045/*
1046 * Set up search table for MIMO
1047 */
889static int rs_switch_to_mimo(struct iwl4965_priv *priv, 1048static int rs_switch_to_mimo(struct iwl4965_priv *priv,
890 struct iwl4965_rate_scale_priv *lq_data, 1049 struct iwl4965_rate_scale_priv *lq_data,
891 struct iwl4965_scale_tbl_info *tbl, int index) 1050 struct iwl4965_scale_tbl_info *tbl, int index)
@@ -906,6 +1065,7 @@ static int rs_switch_to_mimo(struct iwl4965_priv *priv,
906 if (priv->current_assoc_ht.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC) 1065 if (priv->current_assoc_ht.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC)
907 return -1; 1066 return -1;
908 1067
1068 /* Need both Tx chains/antennas to support MIMO */
909 if (!rs_is_both_ant_supp(lq_data->antenna)) 1069 if (!rs_is_both_ant_supp(lq_data->antenna))
910 return -1; 1070 return -1;
911 1071
@@ -943,6 +1103,9 @@ static int rs_switch_to_mimo(struct iwl4965_priv *priv,
943#endif /*CONFIG_IWL4965_HT */ 1103#endif /*CONFIG_IWL4965_HT */
944} 1104}
945 1105
1106/*
1107 * Set up search table for SISO
1108 */
946static int rs_switch_to_siso(struct iwl4965_priv *priv, 1109static int rs_switch_to_siso(struct iwl4965_priv *priv,
947 struct iwl4965_rate_scale_priv *lq_data, 1110 struct iwl4965_rate_scale_priv *lq_data,
948 struct iwl4965_scale_tbl_info *tbl, int index) 1111 struct iwl4965_scale_tbl_info *tbl, int index)
@@ -999,6 +1162,9 @@ static int rs_switch_to_siso(struct iwl4965_priv *priv,
999#endif /*CONFIG_IWL4965_HT */ 1162#endif /*CONFIG_IWL4965_HT */
1000} 1163}
1001 1164
1165/*
1166 * Try to switch to new modulation mode from legacy
1167 */
1002static int rs_move_legacy_other(struct iwl4965_priv *priv, 1168static int rs_move_legacy_other(struct iwl4965_priv *priv,
1003 struct iwl4965_rate_scale_priv *lq_data, 1169 struct iwl4965_rate_scale_priv *lq_data,
1004 int index) 1170 int index)
@@ -1020,12 +1186,17 @@ static int rs_move_legacy_other(struct iwl4965_priv *priv,
1020 1186
1021 search_tbl->lq_type = LQ_NONE; 1187 search_tbl->lq_type = LQ_NONE;
1022 lq_data->action_counter++; 1188 lq_data->action_counter++;
1189
1190 /* Don't change antenna if success has been great */
1023 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1191 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1024 break; 1192 break;
1193
1194 /* Don't change antenna if other one is not connected */
1025 if (!rs_is_other_ant_connected(lq_data->antenna, 1195 if (!rs_is_other_ant_connected(lq_data->antenna,
1026 tbl->antenna_type)) 1196 tbl->antenna_type))
1027 break; 1197 break;
1028 1198
1199 /* Set up search table to try other antenna */
1029 memcpy(search_tbl, tbl, sz); 1200 memcpy(search_tbl, tbl, sz);
1030 1201
1031 rs_toggle_antenna(&(search_tbl->current_rate), 1202 rs_toggle_antenna(&(search_tbl->current_rate),
@@ -1036,6 +1207,8 @@ static int rs_move_legacy_other(struct iwl4965_priv *priv,
1036 1207
1037 case IWL_LEGACY_SWITCH_SISO: 1208 case IWL_LEGACY_SWITCH_SISO:
1038 IWL_DEBUG_HT("LQ: Legacy switch to SISO\n"); 1209 IWL_DEBUG_HT("LQ: Legacy switch to SISO\n");
1210
1211 /* Set up search table to try SISO */
1039 memcpy(search_tbl, tbl, sz); 1212 memcpy(search_tbl, tbl, sz);
1040 search_tbl->lq_type = LQ_SISO; 1213 search_tbl->lq_type = LQ_SISO;
1041 search_tbl->is_SGI = 0; 1214 search_tbl->is_SGI = 0;
@@ -1051,6 +1224,8 @@ static int rs_move_legacy_other(struct iwl4965_priv *priv,
1051 break; 1224 break;
1052 case IWL_LEGACY_SWITCH_MIMO: 1225 case IWL_LEGACY_SWITCH_MIMO:
1053 IWL_DEBUG_HT("LQ: Legacy switch MIMO\n"); 1226 IWL_DEBUG_HT("LQ: Legacy switch MIMO\n");
1227
1228 /* Set up search table to try MIMO */
1054 memcpy(search_tbl, tbl, sz); 1229 memcpy(search_tbl, tbl, sz);
1055 search_tbl->lq_type = LQ_MIMO; 1230 search_tbl->lq_type = LQ_MIMO;
1056 search_tbl->is_SGI = 0; 1231 search_tbl->is_SGI = 0;
@@ -1083,6 +1258,9 @@ static int rs_move_legacy_other(struct iwl4965_priv *priv,
1083 1258
1084} 1259}
1085 1260
1261/*
1262 * Try to switch to new modulation mode from SISO
1263 */
1086static int rs_move_siso_to_other(struct iwl4965_priv *priv, 1264static int rs_move_siso_to_other(struct iwl4965_priv *priv,
1087 struct iwl4965_rate_scale_priv *lq_data, 1265 struct iwl4965_rate_scale_priv *lq_data,
1088 int index) 1266 int index)
@@ -1173,6 +1351,9 @@ static int rs_move_siso_to_other(struct iwl4965_priv *priv,
1173 return 0; 1351 return 0;
1174} 1352}
1175 1353
1354/*
1355 * Try to switch to new modulation mode from MIMO
1356 */
1176static int rs_move_mimo_to_other(struct iwl4965_priv *priv, 1357static int rs_move_mimo_to_other(struct iwl4965_priv *priv,
1177 struct iwl4965_rate_scale_priv *lq_data, 1358 struct iwl4965_rate_scale_priv *lq_data,
1178 int index) 1359 int index)
@@ -1193,6 +1374,8 @@ static int rs_move_mimo_to_other(struct iwl4965_priv *priv,
1193 case IWL_MIMO_SWITCH_ANTENNA_A: 1374 case IWL_MIMO_SWITCH_ANTENNA_A:
1194 case IWL_MIMO_SWITCH_ANTENNA_B: 1375 case IWL_MIMO_SWITCH_ANTENNA_B:
1195 IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n"); 1376 IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n");
1377
1378 /* Set up new search table for SISO */
1196 memcpy(search_tbl, tbl, sz); 1379 memcpy(search_tbl, tbl, sz);
1197 search_tbl->lq_type = LQ_SISO; 1380 search_tbl->lq_type = LQ_SISO;
1198 search_tbl->is_SGI = 0; 1381 search_tbl->is_SGI = 0;
@@ -1212,6 +1395,8 @@ static int rs_move_mimo_to_other(struct iwl4965_priv *priv,
1212 1395
1213 case IWL_MIMO_SWITCH_GI: 1396 case IWL_MIMO_SWITCH_GI:
1214 IWL_DEBUG_HT("LQ: MIMO SWITCH TO GI\n"); 1397 IWL_DEBUG_HT("LQ: MIMO SWITCH TO GI\n");
1398
1399 /* Set up new search table for MIMO */
1215 memcpy(search_tbl, tbl, sz); 1400 memcpy(search_tbl, tbl, sz);
1216 search_tbl->lq_type = LQ_MIMO; 1401 search_tbl->lq_type = LQ_MIMO;
1217 search_tbl->antenna_type = ANT_BOTH; 1402 search_tbl->antenna_type = ANT_BOTH;
@@ -1221,6 +1406,13 @@ static int rs_move_mimo_to_other(struct iwl4965_priv *priv,
1221 else 1406 else
1222 search_tbl->is_SGI = 1; 1407 search_tbl->is_SGI = 1;
1223 lq_data->search_better_tbl = 1; 1408 lq_data->search_better_tbl = 1;
1409
1410 /*
1411 * If active table already uses the fastest possible
1412 * modulation (dual stream with short guard interval),
1413 * and it's working well, there's no need to look
1414 * for a better type of modulation!
1415 */
1224 if ((tbl->lq_type == LQ_MIMO) && 1416 if ((tbl->lq_type == LQ_MIMO) &&
1225 (tbl->is_SGI)) { 1417 (tbl->is_SGI)) {
1226 s32 tpt = lq_data->last_tpt / 100; 1418 s32 tpt = lq_data->last_tpt / 100;
@@ -1253,6 +1445,13 @@ static int rs_move_mimo_to_other(struct iwl4965_priv *priv,
1253 1445
1254} 1446}
1255 1447
1448/*
1449 * Check whether we should continue using same modulation mode, or
1450 * begin search for a new mode, based on:
1451 * 1) # tx successes or failures while using this mode
1452 * 2) # times calling this function
1453 * 3) elapsed time in this mode (not used, for now)
1454 */
1256static void rs_stay_in_table(struct iwl4965_rate_scale_priv *lq_data) 1455static void rs_stay_in_table(struct iwl4965_rate_scale_priv *lq_data)
1257{ 1456{
1258 struct iwl4965_scale_tbl_info *tbl; 1457 struct iwl4965_scale_tbl_info *tbl;
@@ -1264,15 +1463,27 @@ static void rs_stay_in_table(struct iwl4965_rate_scale_priv *lq_data)
1264 1463
1265 tbl = &(lq_data->lq_info[active_tbl]); 1464 tbl = &(lq_data->lq_info[active_tbl]);
1266 1465
1466 /* If we've been disallowing search, see if we should now allow it */
1267 if (lq_data->stay_in_tbl) { 1467 if (lq_data->stay_in_tbl) {
1268 1468
1469 /* Elapsed time using current modulation mode */
1269 if (lq_data->flush_timer) 1470 if (lq_data->flush_timer)
1270 flush_interval_passed = 1471 flush_interval_passed =
1271 time_after(jiffies, 1472 time_after(jiffies,
1272 (unsigned long)(lq_data->flush_timer + 1473 (unsigned long)(lq_data->flush_timer +
1273 IWL_RATE_SCALE_FLUSH_INTVL)); 1474 IWL_RATE_SCALE_FLUSH_INTVL));
1274 1475
1476 /* For now, disable the elapsed time criterion */
1275 flush_interval_passed = 0; 1477 flush_interval_passed = 0;
1478
1479 /*
1480 * Check if we should allow search for new modulation mode.
1481 * If many frames have failed or succeeded, or we've used
1482 * this same modulation for a long time, allow search, and
1483 * reset history stats that keep track of whether we should
1484 * allow a new search. Also (below) reset all bitmaps and
1485 * stats in active history.
1486 */
1276 if ((lq_data->total_failed > lq_data->max_failure_limit) || 1487 if ((lq_data->total_failed > lq_data->max_failure_limit) ||
1277 (lq_data->total_success > lq_data->max_success_limit) || 1488 (lq_data->total_success > lq_data->max_success_limit) ||
1278 ((!lq_data->search_better_tbl) && (lq_data->flush_timer) 1489 ((!lq_data->search_better_tbl) && (lq_data->flush_timer)
@@ -1281,10 +1492,19 @@ static void rs_stay_in_table(struct iwl4965_rate_scale_priv *lq_data)
1281 lq_data->total_failed, 1492 lq_data->total_failed,
1282 lq_data->total_success, 1493 lq_data->total_success,
1283 flush_interval_passed); 1494 flush_interval_passed);
1284 lq_data->stay_in_tbl = 0; 1495
1496 /* Allow search for new mode */
1497 lq_data->stay_in_tbl = 0; /* only place reset */
1285 lq_data->total_failed = 0; 1498 lq_data->total_failed = 0;
1286 lq_data->total_success = 0; 1499 lq_data->total_success = 0;
1287 lq_data->flush_timer = 0; 1500 lq_data->flush_timer = 0;
1501
1502 /*
1503 * Else if we've used this modulation mode enough repetitions
1504 * (regardless of elapsed time or success/failure), reset
1505 * history bitmaps and rate-specific stats for all rates in
1506 * active table.
1507 */
1288 } else { 1508 } else {
1289 lq_data->table_count++; 1509 lq_data->table_count++;
1290 if (lq_data->table_count >= 1510 if (lq_data->table_count >=
@@ -1298,6 +1518,9 @@ static void rs_stay_in_table(struct iwl4965_rate_scale_priv *lq_data)
1298 } 1518 }
1299 } 1519 }
1300 1520
1521 /* If transitioning to allow "search", reset all history
1522 * bitmaps and stats in active table (this will become the new
1523 * "search" table). */
1301 if (!lq_data->stay_in_tbl) { 1524 if (!lq_data->stay_in_tbl) {
1302 for (i = 0; i < IWL_RATE_COUNT; i++) 1525 for (i = 0; i < IWL_RATE_COUNT; i++)
1303 rs_rate_scale_clear_window(&(tbl->win[i])); 1526 rs_rate_scale_clear_window(&(tbl->win[i]));
@@ -1305,6 +1528,9 @@ static void rs_stay_in_table(struct iwl4965_rate_scale_priv *lq_data)
1305 } 1528 }
1306} 1529}
1307 1530
1531/*
1532 * Do rate scaling and search for new modulation mode.
1533 */
1308static void rs_rate_scale_perform(struct iwl4965_priv *priv, 1534static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1309 struct net_device *dev, 1535 struct net_device *dev,
1310 struct ieee80211_hdr *hdr, 1536 struct ieee80211_hdr *hdr,
@@ -1350,6 +1576,11 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1350 } 1576 }
1351 lq_data = (struct iwl4965_rate_scale_priv *)sta->rate_ctrl_priv; 1577 lq_data = (struct iwl4965_rate_scale_priv *)sta->rate_ctrl_priv;
1352 1578
1579 /*
1580 * Select rate-scale / modulation-mode table to work with in
1581 * the rest of this function: "search" if searching for better
1582 * modulation mode, or "active" if doing rate scaling within a mode.
1583 */
1353 if (!lq_data->search_better_tbl) 1584 if (!lq_data->search_better_tbl)
1354 active_tbl = lq_data->active_tbl; 1585 active_tbl = lq_data->active_tbl;
1355 else 1586 else
@@ -1358,11 +1589,13 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1358 tbl = &(lq_data->lq_info[active_tbl]); 1589 tbl = &(lq_data->lq_info[active_tbl]);
1359 is_green = lq_data->is_green; 1590 is_green = lq_data->is_green;
1360 1591
1592 /* current tx rate */
1361 index = sta->last_txrate; 1593 index = sta->last_txrate;
1362 1594
1363 IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index, 1595 IWL_DEBUG_RATE("Rate scale index %d for type %d\n", index,
1364 tbl->lq_type); 1596 tbl->lq_type);
1365 1597
1598 /* rates available for this association, and for modulation mode */
1366 rs_get_supported_rates(lq_data, hdr, tbl->lq_type, 1599 rs_get_supported_rates(lq_data, hdr, tbl->lq_type,
1367 &rate_mask); 1600 &rate_mask);
1368 1601
@@ -1371,6 +1604,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1371 /* mask with station rate restriction */ 1604 /* mask with station rate restriction */
1372 if (is_legacy(tbl->lq_type)) { 1605 if (is_legacy(tbl->lq_type)) {
1373 if (lq_data->phymode == (u8) MODE_IEEE80211A) 1606 if (lq_data->phymode == (u8) MODE_IEEE80211A)
1607 /* supp_rates has no CCK bits in A mode */
1374 rate_scale_index_msk = (u16) (rate_mask & 1608 rate_scale_index_msk = (u16) (rate_mask &
1375 (lq_data->supp_rates << IWL_FIRST_OFDM_RATE)); 1609 (lq_data->supp_rates << IWL_FIRST_OFDM_RATE));
1376 else 1610 else
@@ -1383,11 +1617,13 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1383 if (!rate_scale_index_msk) 1617 if (!rate_scale_index_msk)
1384 rate_scale_index_msk = rate_mask; 1618 rate_scale_index_msk = rate_mask;
1385 1619
1620 /* If current rate is no longer supported on current association,
1621 * or user changed preferences for rates, find a new supported rate. */
1386 if (index < 0 || !((1 << index) & rate_scale_index_msk)) { 1622 if (index < 0 || !((1 << index) & rate_scale_index_msk)) {
1387 index = IWL_INVALID_VALUE; 1623 index = IWL_INVALID_VALUE;
1388 update_lq = 1; 1624 update_lq = 1;
1389 1625
1390 /* get the lowest available rate */ 1626 /* get the highest available rate */
1391 for (i = 0; i <= IWL_RATE_COUNT; i++) { 1627 for (i = 0; i <= IWL_RATE_COUNT; i++) {
1392 if ((1 << i) & rate_scale_index_msk) 1628 if ((1 << i) & rate_scale_index_msk)
1393 index = i; 1629 index = i;
@@ -1399,11 +1635,19 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1399 } 1635 }
1400 } 1636 }
1401 1637
1638 /* Get expected throughput table and history window for current rate */
1402 if (!tbl->expected_tpt) 1639 if (!tbl->expected_tpt)
1403 rs_get_expected_tpt_table(lq_data, tbl); 1640 rs_get_expected_tpt_table(lq_data, tbl);
1404 1641
1405 window = &(tbl->win[index]); 1642 window = &(tbl->win[index]);
1406 1643
1644 /*
1645 * If there is not enough history to calculate actual average
1646 * throughput, keep analyzing results of more tx frames, without
1647 * changing rate or mode (bypass most of the rest of this function).
1648 * Set up new rate table in uCode only if old rate is not supported
1649 * in current association (use new rate found above).
1650 */
1407 fail_count = window->counter - window->success_counter; 1651 fail_count = window->counter - window->success_counter;
1408 if (((fail_count < IWL_RATE_MIN_FAILURE_TH) && 1652 if (((fail_count < IWL_RATE_MIN_FAILURE_TH) &&
1409 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH)) 1653 (window->success_counter < IWL_RATE_MIN_SUCCESS_TH))
@@ -1411,8 +1655,15 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1411 IWL_DEBUG_RATE("LQ: still below TH succ %d total %d " 1655 IWL_DEBUG_RATE("LQ: still below TH succ %d total %d "
1412 "for index %d\n", 1656 "for index %d\n",
1413 window->success_counter, window->counter, index); 1657 window->success_counter, window->counter, index);
1658
1659 /* Can't calculate this yet; not enough history */
1414 window->average_tpt = IWL_INVALID_VALUE; 1660 window->average_tpt = IWL_INVALID_VALUE;
1661
1662 /* Should we stay with this modulation mode,
1663 * or search for a new one? */
1415 rs_stay_in_table(lq_data); 1664 rs_stay_in_table(lq_data);
1665
1666 /* Set up new rate table in uCode, if needed */
1416 if (update_lq) { 1667 if (update_lq) {
1417 rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); 1668 rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
1418 rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq); 1669 rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq);
@@ -1420,13 +1671,19 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1420 } 1671 }
1421 goto out; 1672 goto out;
1422 1673
1674 /* Else we have enough samples; calculate estimate of
1675 * actual average throughput */
1423 } else 1676 } else
1424 window->average_tpt = ((window->success_ratio * 1677 window->average_tpt = ((window->success_ratio *
1425 tbl->expected_tpt[index] + 64) / 128); 1678 tbl->expected_tpt[index] + 64) / 128);
1426 1679
1680 /* If we are searching for better modulation mode, check success. */
1427 if (lq_data->search_better_tbl) { 1681 if (lq_data->search_better_tbl) {
1428 int success_limit = IWL_RATE_SCALE_SWITCH; 1682 int success_limit = IWL_RATE_SCALE_SWITCH;
1429 1683
1684 /* If good success, continue using the "search" mode;
1685 * no need to send new link quality command, since we're
1686 * continuing to use the setup that we've been trying. */
1430 if ((window->success_ratio > success_limit) || 1687 if ((window->success_ratio > success_limit) ||
1431 (window->average_tpt > lq_data->last_tpt)) { 1688 (window->average_tpt > lq_data->last_tpt)) {
1432 if (!is_legacy(tbl->lq_type)) { 1689 if (!is_legacy(tbl->lq_type)) {
@@ -1438,55 +1695,78 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1438 lq_data->last_tpt); 1695 lq_data->last_tpt);
1439 lq_data->enable_counter = 1; 1696 lq_data->enable_counter = 1;
1440 } 1697 }
1698 /* Swap tables; "search" becomes "active" */
1441 lq_data->active_tbl = active_tbl; 1699 lq_data->active_tbl = active_tbl;
1442 current_tpt = window->average_tpt; 1700 current_tpt = window->average_tpt;
1701
1702 /* Else poor success; go back to mode in "active" table */
1443 } else { 1703 } else {
1704 /* Nullify "search" table */
1444 tbl->lq_type = LQ_NONE; 1705 tbl->lq_type = LQ_NONE;
1706
1707 /* Revert to "active" table */
1445 active_tbl = lq_data->active_tbl; 1708 active_tbl = lq_data->active_tbl;
1446 tbl = &(lq_data->lq_info[active_tbl]); 1709 tbl = &(lq_data->lq_info[active_tbl]);
1447 1710
1711 /* Revert to "active" rate and throughput info */
1448 index = iwl4965_rate_index_from_plcp( 1712 index = iwl4965_rate_index_from_plcp(
1449 tbl->current_rate.rate_n_flags); 1713 tbl->current_rate.rate_n_flags);
1714 current_tpt = lq_data->last_tpt;
1450 1715
1716 /* Need to set up a new rate table in uCode */
1451 update_lq = 1; 1717 update_lq = 1;
1452 current_tpt = lq_data->last_tpt;
1453 IWL_DEBUG_HT("XXY GO BACK TO OLD TABLE\n"); 1718 IWL_DEBUG_HT("XXY GO BACK TO OLD TABLE\n");
1454 } 1719 }
1720
1721 /* Either way, we've made a decision; modulation mode
1722 * search is done, allow rate adjustment next time. */
1455 lq_data->search_better_tbl = 0; 1723 lq_data->search_better_tbl = 0;
1456 done_search = 1; 1724 done_search = 1; /* Don't switch modes below! */
1457 goto lq_update; 1725 goto lq_update;
1458 } 1726 }
1459 1727
1728 /* (Else) not in search of better modulation mode, try for better
1729 * starting rate, while staying in this mode. */
1460 high_low = rs_get_adjacent_rate(index, rate_scale_index_msk, 1730 high_low = rs_get_adjacent_rate(index, rate_scale_index_msk,
1461 tbl->lq_type); 1731 tbl->lq_type);
1462 low = high_low & 0xff; 1732 low = high_low & 0xff;
1463 high = (high_low >> 8) & 0xff; 1733 high = (high_low >> 8) & 0xff;
1464 1734
1735 /* Collect measured throughputs for current and adjacent rates */
1465 current_tpt = window->average_tpt; 1736 current_tpt = window->average_tpt;
1466
1467 if (low != IWL_RATE_INVALID) 1737 if (low != IWL_RATE_INVALID)
1468 low_tpt = tbl->win[low].average_tpt; 1738 low_tpt = tbl->win[low].average_tpt;
1469
1470 if (high != IWL_RATE_INVALID) 1739 if (high != IWL_RATE_INVALID)
1471 high_tpt = tbl->win[high].average_tpt; 1740 high_tpt = tbl->win[high].average_tpt;
1472 1741
1473 1742 /* Assume rate increase */
1474 scale_action = 1; 1743 scale_action = 1;
1475 1744
1745 /* Too many failures, decrease rate */
1476 if ((window->success_ratio <= IWL_RATE_DECREASE_TH) || 1746 if ((window->success_ratio <= IWL_RATE_DECREASE_TH) ||
1477 (current_tpt == 0)) { 1747 (current_tpt == 0)) {
1478 IWL_DEBUG_RATE("decrease rate because of low success_ratio\n"); 1748 IWL_DEBUG_RATE("decrease rate because of low success_ratio\n");
1479 scale_action = -1; 1749 scale_action = -1;
1750
1751 /* No throughput measured yet for adjacent rates; try increase. */
1480 } else if ((low_tpt == IWL_INVALID_VALUE) && 1752 } else if ((low_tpt == IWL_INVALID_VALUE) &&
1481 (high_tpt == IWL_INVALID_VALUE)) 1753 (high_tpt == IWL_INVALID_VALUE))
1482 scale_action = 1; 1754 scale_action = 1;
1755
1756 /* Both adjacent throughputs are measured, but neither one has better
1757 * throughput; we're using the best rate, don't change it! */
1483 else if ((low_tpt != IWL_INVALID_VALUE) && 1758 else if ((low_tpt != IWL_INVALID_VALUE) &&
1484 (high_tpt != IWL_INVALID_VALUE) && 1759 (high_tpt != IWL_INVALID_VALUE) &&
1485 (low_tpt < current_tpt) && 1760 (low_tpt < current_tpt) &&
1486 (high_tpt < current_tpt)) 1761 (high_tpt < current_tpt))
1487 scale_action = 0; 1762 scale_action = 0;
1763
1764 /* At least one adjacent rate's throughput is measured,
1765 * and may have better performance. */
1488 else { 1766 else {
1767 /* Higher adjacent rate's throughput is measured */
1489 if (high_tpt != IWL_INVALID_VALUE) { 1768 if (high_tpt != IWL_INVALID_VALUE) {
1769 /* Higher rate has better throughput */
1490 if (high_tpt > current_tpt) 1770 if (high_tpt > current_tpt)
1491 scale_action = 1; 1771 scale_action = 1;
1492 else { 1772 else {
@@ -1494,7 +1774,10 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1494 ("decrease rate because of high tpt\n"); 1774 ("decrease rate because of high tpt\n");
1495 scale_action = -1; 1775 scale_action = -1;
1496 } 1776 }
1777
1778 /* Lower adjacent rate's throughput is measured */
1497 } else if (low_tpt != IWL_INVALID_VALUE) { 1779 } else if (low_tpt != IWL_INVALID_VALUE) {
1780 /* Lower rate has better throughput */
1498 if (low_tpt > current_tpt) { 1781 if (low_tpt > current_tpt) {
1499 IWL_DEBUG_RATE 1782 IWL_DEBUG_RATE
1500 ("decrease rate because of low tpt\n"); 1783 ("decrease rate because of low tpt\n");
@@ -1504,23 +1787,30 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1504 } 1787 }
1505 } 1788 }
1506 1789
1790 /* Sanity check; asked for decrease, but success rate or throughput
1791 * has been good at old rate. Don't change it. */
1507 if (scale_action == -1) { 1792 if (scale_action == -1) {
1508 if ((low != IWL_RATE_INVALID) && 1793 if ((low != IWL_RATE_INVALID) &&
1509 ((window->success_ratio > IWL_RATE_HIGH_TH) || 1794 ((window->success_ratio > IWL_RATE_HIGH_TH) ||
1510 (current_tpt > (100 * tbl->expected_tpt[low])))) 1795 (current_tpt > (100 * tbl->expected_tpt[low]))))
1511 scale_action = 0; 1796 scale_action = 0;
1797
1798 /* Sanity check; asked for increase, but success rate has not been great
1799 * even at old rate, higher rate will be worse. Don't change it. */
1512 } else if ((scale_action == 1) && 1800 } else if ((scale_action == 1) &&
1513 (window->success_ratio < IWL_RATE_INCREASE_TH)) 1801 (window->success_ratio < IWL_RATE_INCREASE_TH))
1514 scale_action = 0; 1802 scale_action = 0;
1515 1803
1516 switch (scale_action) { 1804 switch (scale_action) {
1517 case -1: 1805 case -1:
1806 /* Decrease starting rate, update uCode's rate table */
1518 if (low != IWL_RATE_INVALID) { 1807 if (low != IWL_RATE_INVALID) {
1519 update_lq = 1; 1808 update_lq = 1;
1520 index = low; 1809 index = low;
1521 } 1810 }
1522 break; 1811 break;
1523 case 1: 1812 case 1:
1813 /* Increase starting rate, update uCode's rate table */
1524 if (high != IWL_RATE_INVALID) { 1814 if (high != IWL_RATE_INVALID) {
1525 update_lq = 1; 1815 update_lq = 1;
1526 index = high; 1816 index = high;
@@ -1528,6 +1818,7 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1528 1818
1529 break; 1819 break;
1530 case 0: 1820 case 0:
1821 /* No change */
1531 default: 1822 default:
1532 break; 1823 break;
1533 } 1824 }
@@ -1537,16 +1828,28 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1537 index, scale_action, low, high, tbl->lq_type); 1828 index, scale_action, low, high, tbl->lq_type);
1538 1829
1539 lq_update: 1830 lq_update:
1831 /* Replace uCode's rate table for the destination station. */
1540 if (update_lq) { 1832 if (update_lq) {
1541 rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); 1833 rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
1542 rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq); 1834 rs_fill_link_cmd(lq_data, &mcs_rate, &lq_data->lq);
1543 rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC); 1835 rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC);
1544 } 1836 }
1837
1838 /* Should we stay with this modulation mode, or search for a new one? */
1545 rs_stay_in_table(lq_data); 1839 rs_stay_in_table(lq_data);
1546 1840
1841 /*
1842 * Search for new modulation mode if we're:
1843 * 1) Not changing rates right now
1844 * 2) Not just finishing up a search
1845 * 3) Allowing a new search
1846 */
1547 if (!update_lq && !done_search && !lq_data->stay_in_tbl) { 1847 if (!update_lq && !done_search && !lq_data->stay_in_tbl) {
1848 /* Save current throughput to compare with "search" throughput*/
1548 lq_data->last_tpt = current_tpt; 1849 lq_data->last_tpt = current_tpt;
1549 1850
1851 /* Select a new "search" modulation mode to try.
1852 * If one is found, set up the new "search" table. */
1550 if (is_legacy(tbl->lq_type)) 1853 if (is_legacy(tbl->lq_type))
1551 rs_move_legacy_other(priv, lq_data, index); 1854 rs_move_legacy_other(priv, lq_data, index);
1552 else if (is_siso(tbl->lq_type)) 1855 else if (is_siso(tbl->lq_type))
@@ -1554,11 +1857,14 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1554 else 1857 else
1555 rs_move_mimo_to_other(priv, lq_data, index); 1858 rs_move_mimo_to_other(priv, lq_data, index);
1556 1859
1860 /* If new "search" mode was selected, set up in uCode table */
1557 if (lq_data->search_better_tbl) { 1861 if (lq_data->search_better_tbl) {
1862 /* Access the "search" table, clear its history. */
1558 tbl = &(lq_data->lq_info[(1 - lq_data->active_tbl)]); 1863 tbl = &(lq_data->lq_info[(1 - lq_data->active_tbl)]);
1559 for (i = 0; i < IWL_RATE_COUNT; i++) 1864 for (i = 0; i < IWL_RATE_COUNT; i++)
1560 rs_rate_scale_clear_window(&(tbl->win[i])); 1865 rs_rate_scale_clear_window(&(tbl->win[i]));
1561 1866
1867 /* Use new "search" start rate */
1562 index = iwl4965_rate_index_from_plcp( 1868 index = iwl4965_rate_index_from_plcp(
1563 tbl->current_rate.rate_n_flags); 1869 tbl->current_rate.rate_n_flags);
1564 1870
@@ -1568,8 +1874,13 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1568 &lq_data->lq); 1874 &lq_data->lq);
1569 rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC); 1875 rs_send_lq_cmd(priv, &lq_data->lq, CMD_ASYNC);
1570 } 1876 }
1571 tbl1 = &(lq_data->lq_info[lq_data->active_tbl]);
1572 1877
1878 /* If the "active" (non-search) mode was legacy,
1879 * and we've tried switching antennas,
1880 * but we haven't been able to try HT modes (not available),
1881 * stay with best antenna legacy modulation for a while
1882 * before next round of mode comparisons. */
1883 tbl1 = &(lq_data->lq_info[lq_data->active_tbl]);
1573 if (is_legacy(tbl1->lq_type) && 1884 if (is_legacy(tbl1->lq_type) &&
1574#ifdef CONFIG_IWL4965_HT 1885#ifdef CONFIG_IWL4965_HT
1575 !priv->current_assoc_ht.is_ht && 1886 !priv->current_assoc_ht.is_ht &&
@@ -1580,9 +1891,13 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1580 rs_set_stay_in_table(1, lq_data); 1891 rs_set_stay_in_table(1, lq_data);
1581 } 1892 }
1582 1893
1894 /* If we're in an HT mode, and all 3 mode switch actions
1895 * have been tried and compared, stay in this best modulation
1896 * mode for a while before next round of mode comparisons. */
1583 if (lq_data->enable_counter && 1897 if (lq_data->enable_counter &&
1584 (lq_data->action_counter >= IWL_ACTION_LIMIT)) { 1898 (lq_data->action_counter >= IWL_ACTION_LIMIT)) {
1585#ifdef CONFIG_IWL4965_HT_AGG 1899#ifdef CONFIG_IWL4965_HT_AGG
1900 /* If appropriate, set up aggregation! */
1586 if ((lq_data->last_tpt > TID_AGG_TPT_THREHOLD) && 1901 if ((lq_data->last_tpt > TID_AGG_TPT_THREHOLD) &&
1587 (priv->lq_mngr.agg_ctrl.auto_agg)) { 1902 (priv->lq_mngr.agg_ctrl.auto_agg)) {
1588 priv->lq_mngr.agg_ctrl.tid_retry = 1903 priv->lq_mngr.agg_ctrl.tid_retry =
@@ -1593,6 +1908,14 @@ static void rs_rate_scale_perform(struct iwl4965_priv *priv,
1593 lq_data->action_counter = 0; 1908 lq_data->action_counter = 0;
1594 rs_set_stay_in_table(0, lq_data); 1909 rs_set_stay_in_table(0, lq_data);
1595 } 1910 }
1911
1912 /*
1913 * Else, don't search for a new modulation mode.
1914 * Put new timestamp in stay-in-modulation-mode flush timer if:
1915 * 1) Not changing rates right now
1916 * 2) Not just finishing up a search
1917 * 3) flush timer is empty
1918 */
1596 } else { 1919 } else {
1597 if ((!update_lq) && (!done_search) && (!lq_data->flush_timer)) 1920 if ((!update_lq) && (!done_search) && (!lq_data->flush_timer))
1598 lq_data->flush_timer = jiffies; 1921 lq_data->flush_timer = jiffies;
@@ -1789,15 +2112,14 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
1789 priv->assoc_station_added = 1; 2112 priv->assoc_station_added = 1;
1790 } 2113 }
1791 2114
2115 /* Find highest tx rate supported by hardware and destination station */
1792 for (i = 0; i < mode->num_rates; i++) { 2116 for (i = 0; i < mode->num_rates; i++) {
1793 if ((sta->supp_rates & BIT(i)) && 2117 if ((sta->supp_rates & BIT(i)) &&
1794 (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED)) 2118 (mode->rates[i].flags & IEEE80211_RATE_SUPPORTED))
1795 sta->txrate = i; 2119 sta->txrate = i;
1796 } 2120 }
1797 sta->last_txrate = sta->txrate; 2121 sta->last_txrate = sta->txrate;
1798 /* For MODE_IEEE80211A mode cck rate are at end 2122 /* For MODE_IEEE80211A, cck rates are at end of rate table */
1799 * rate table
1800 */
1801 if (local->hw.conf.phymode == MODE_IEEE80211A) 2123 if (local->hw.conf.phymode == MODE_IEEE80211A)
1802 sta->last_txrate += IWL_FIRST_OFDM_RATE; 2124 sta->last_txrate += IWL_FIRST_OFDM_RATE;
1803 2125
@@ -1810,11 +2132,16 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
1810 crl->active_rate_basic = priv->active_rate_basic; 2132 crl->active_rate_basic = priv->active_rate_basic;
1811 crl->phymode = priv->phymode; 2133 crl->phymode = priv->phymode;
1812#ifdef CONFIG_IWL4965_HT 2134#ifdef CONFIG_IWL4965_HT
2135 /*
2136 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
2137 * supp_rates[] does not; shift to convert format, force 9 MBits off.
2138 */
1813 crl->active_siso_rate = (priv->current_assoc_ht.supp_rates[0] << 1); 2139 crl->active_siso_rate = (priv->current_assoc_ht.supp_rates[0] << 1);
1814 crl->active_siso_rate |= (priv->current_assoc_ht.supp_rates[0] & 0x1); 2140 crl->active_siso_rate |= (priv->current_assoc_ht.supp_rates[0] & 0x1);
1815 crl->active_siso_rate &= ~((u16)0x2); 2141 crl->active_siso_rate &= ~((u16)0x2);
1816 crl->active_siso_rate = crl->active_siso_rate << IWL_FIRST_OFDM_RATE; 2142 crl->active_siso_rate = crl->active_siso_rate << IWL_FIRST_OFDM_RATE;
1817 2143
2144 /* Same here */
1818 crl->active_mimo_rate = (priv->current_assoc_ht.supp_rates[1] << 1); 2145 crl->active_mimo_rate = (priv->current_assoc_ht.supp_rates[1] << 1);
1819 crl->active_mimo_rate |= (priv->current_assoc_ht.supp_rates[1] & 0x1); 2146 crl->active_mimo_rate |= (priv->current_assoc_ht.supp_rates[1] & 0x1);
1820 crl->active_mimo_rate &= ~((u16)0x2); 2147 crl->active_mimo_rate &= ~((u16)0x2);
@@ -1844,11 +2171,14 @@ static void rs_fill_link_cmd(struct iwl4965_rate_scale_priv *lq_data,
1844 struct iwl4965_rate new_rate; 2171 struct iwl4965_rate new_rate;
1845 struct iwl4965_scale_tbl_info tbl_type = { 0 }; 2172 struct iwl4965_scale_tbl_info tbl_type = { 0 };
1846 2173
2174 /* Override starting rate (index 0) if needed for debug purposes */
1847 rs_dbgfs_set_mcs(lq_data, tx_mcs, index); 2175 rs_dbgfs_set_mcs(lq_data, tx_mcs, index);
1848 2176
2177 /* Interpret rate_n_flags */
1849 rs_get_tbl_info_from_mcs(tx_mcs, lq_data->phymode, 2178 rs_get_tbl_info_from_mcs(tx_mcs, lq_data->phymode,
1850 &tbl_type, &rate_idx); 2179 &tbl_type, &rate_idx);
1851 2180
2181 /* How many times should we repeat the initial rate? */
1852 if (is_legacy(tbl_type.lq_type)) { 2182 if (is_legacy(tbl_type.lq_type)) {
1853 ant_toggle_count = 1; 2183 ant_toggle_count = 1;
1854 repeat_rate = IWL_NUMBER_TRY; 2184 repeat_rate = IWL_NUMBER_TRY;
@@ -1857,19 +2187,27 @@ static void rs_fill_link_cmd(struct iwl4965_rate_scale_priv *lq_data,
1857 2187
1858 lq_cmd->general_params.mimo_delimiter = 2188 lq_cmd->general_params.mimo_delimiter =
1859 is_mimo(tbl_type.lq_type) ? 1 : 0; 2189 is_mimo(tbl_type.lq_type) ? 1 : 0;
2190
2191 /* Fill 1st table entry (index 0) */
1860 lq_cmd->rs_table[index].rate_n_flags = 2192 lq_cmd->rs_table[index].rate_n_flags =
1861 cpu_to_le32(tx_mcs->rate_n_flags); 2193 cpu_to_le32(tx_mcs->rate_n_flags);
1862 new_rate.rate_n_flags = tx_mcs->rate_n_flags; 2194 new_rate.rate_n_flags = tx_mcs->rate_n_flags;
1863 2195
1864 if (is_mimo(tbl_type.lq_type) || (tbl_type.antenna_type == ANT_MAIN)) 2196 if (is_mimo(tbl_type.lq_type) || (tbl_type.antenna_type == ANT_MAIN))
1865 lq_cmd->general_params.single_stream_ant_msk = 1; 2197 lq_cmd->general_params.single_stream_ant_msk
2198 = LINK_QUAL_ANT_A_MSK;
1866 else 2199 else
1867 lq_cmd->general_params.single_stream_ant_msk = 2; 2200 lq_cmd->general_params.single_stream_ant_msk
2201 = LINK_QUAL_ANT_B_MSK;
1868 2202
1869 index++; 2203 index++;
1870 repeat_rate--; 2204 repeat_rate--;
1871 2205
2206 /* Fill rest of rate table */
1872 while (index < LINK_QUAL_MAX_RETRY_NUM) { 2207 while (index < LINK_QUAL_MAX_RETRY_NUM) {
2208 /* Repeat initial/next rate.
2209 * For legacy IWL_NUMBER_TRY == 1, this loop will not execute.
2210 * For HT IWL_HT_NUMBER_TRY == 3, this executes twice. */
1873 while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) { 2211 while (repeat_rate > 0 && (index < LINK_QUAL_MAX_RETRY_NUM)) {
1874 if (is_legacy(tbl_type.lq_type)) { 2212 if (is_legacy(tbl_type.lq_type)) {
1875 if (ant_toggle_count < 2213 if (ant_toggle_count <
@@ -1881,7 +2219,10 @@ static void rs_fill_link_cmd(struct iwl4965_rate_scale_priv *lq_data,
1881 } 2219 }
1882 } 2220 }
1883 2221
2222 /* Override next rate if needed for debug purposes */
1884 rs_dbgfs_set_mcs(lq_data, &new_rate, index); 2223 rs_dbgfs_set_mcs(lq_data, &new_rate, index);
2224
2225 /* Fill next table entry */
1885 lq_cmd->rs_table[index].rate_n_flags = 2226 lq_cmd->rs_table[index].rate_n_flags =
1886 cpu_to_le32(new_rate.rate_n_flags); 2227 cpu_to_le32(new_rate.rate_n_flags);
1887 repeat_rate--; 2228 repeat_rate--;
@@ -1891,12 +2232,17 @@ static void rs_fill_link_cmd(struct iwl4965_rate_scale_priv *lq_data,
1891 rs_get_tbl_info_from_mcs(&new_rate, lq_data->phymode, &tbl_type, 2232 rs_get_tbl_info_from_mcs(&new_rate, lq_data->phymode, &tbl_type,
1892 &rate_idx); 2233 &rate_idx);
1893 2234
2235 /* Indicate to uCode which entries might be MIMO.
2236 * If initial rate was MIMO, this will finally end up
2237 * as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
1894 if (is_mimo(tbl_type.lq_type)) 2238 if (is_mimo(tbl_type.lq_type))
1895 lq_cmd->general_params.mimo_delimiter = index; 2239 lq_cmd->general_params.mimo_delimiter = index;
1896 2240
2241 /* Get next rate */
1897 rs_get_lower_rate(lq_data, &tbl_type, rate_idx, 2242 rs_get_lower_rate(lq_data, &tbl_type, rate_idx,
1898 use_ht_possible, &new_rate); 2243 use_ht_possible, &new_rate);
1899 2244
2245 /* How many times should we repeat the next rate? */
1900 if (is_legacy(tbl_type.lq_type)) { 2246 if (is_legacy(tbl_type.lq_type)) {
1901 if (ant_toggle_count < NUM_TRY_BEFORE_ANTENNA_TOGGLE) 2247 if (ant_toggle_count < NUM_TRY_BEFORE_ANTENNA_TOGGLE)
1902 ant_toggle_count++; 2248 ant_toggle_count++;
@@ -1908,9 +2254,14 @@ static void rs_fill_link_cmd(struct iwl4965_rate_scale_priv *lq_data,
1908 } else 2254 } else
1909 repeat_rate = IWL_HT_NUMBER_TRY; 2255 repeat_rate = IWL_HT_NUMBER_TRY;
1910 2256
2257 /* Don't allow HT rates after next pass.
2258 * rs_get_lower_rate() will change type to LQ_A or LQ_G. */
1911 use_ht_possible = 0; 2259 use_ht_possible = 0;
1912 2260
2261 /* Override next rate if needed for debug purposes */
1913 rs_dbgfs_set_mcs(lq_data, &new_rate, index); 2262 rs_dbgfs_set_mcs(lq_data, &new_rate, index);
2263
2264 /* Fill next table entry */
1914 lq_cmd->rs_table[index].rate_n_flags = 2265 lq_cmd->rs_table[index].rate_n_flags =
1915 cpu_to_le32(new_rate.rate_n_flags); 2266 cpu_to_le32(new_rate.rate_n_flags);
1916 2267
@@ -2006,9 +2357,9 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2006 else 2357 else
2007 rs_priv->dbg_fixed.rate_n_flags = 0; 2358 rs_priv->dbg_fixed.rate_n_flags = 0;
2008 2359
2009 rs_priv->active_rate = 0x0FFF; 2360 rs_priv->active_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
2010 rs_priv->active_siso_rate = 0x1FD0; 2361 rs_priv->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2011 rs_priv->active_mimo_rate = 0x1FD0; 2362 rs_priv->active_mimo_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2012 2363
2013 IWL_DEBUG_RATE("sta_id %d rate 0x%X\n", 2364 IWL_DEBUG_RATE("sta_id %d rate 0x%X\n",
2014 rs_priv->lq.sta_id, rs_priv->dbg_fixed.rate_n_flags); 2365 rs_priv->lq.sta_id, rs_priv->dbg_fixed.rate_n_flags);
@@ -2209,7 +2560,7 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
2209 2560
2210 /* Display the average rate of all samples taken. 2561 /* Display the average rate of all samples taken.
2211 * 2562 *
2212 * NOTE: We multiple # of samples by 2 since the IEEE measurement 2563 * NOTE: We multiply # of samples by 2 since the IEEE measurement
2213 * added from iwl4965_rates is actually 2X the rate */ 2564 * added from iwl4965_rates is actually 2X the rate */
2214 if (samples) 2565 if (samples)
2215 count += sprintf(&buf[count], 2566 count += sprintf(&buf[count],