aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Cohen <guy.cohen@intel.com>2008-04-23 20:14:57 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-07 15:02:18 -0400
commit39e885049d9d5e6a65bb2543f82e136c02c253b5 (patch)
tree86edc7552e5b0ad423845f0ec91b6cd809460e67
parent399f490067992715044cbf2be1923e2f613b2e18 (diff)
iwlwifi: TLC modifications
1. Merge TLC fixes from AP support code 2. Remove struct iwl4965_rate 3. Misc code restructuring Signed-off-by: Guy Cohen <guy.cohen@intel.com> Signed-off-by: Tomas Winkler <tomas.winkler@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.c434
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c31
2 files changed, 221 insertions, 244 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index 31a0451f7a4d..7c55aa9a2ba9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -64,10 +64,6 @@ static u8 rs_ht_to_legacy[] = {
64 IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX 64 IWL_RATE_48M_INDEX, IWL_RATE_54M_INDEX
65}; 65};
66 66
67struct iwl4965_rate {
68 u32 rate_n_flags;
69} __attribute__ ((packed));
70
71/** 67/**
72 * struct iwl4965_rate_scale_data -- tx success history for one rate 68 * struct iwl4965_rate_scale_data -- tx success history for one rate
73 */ 69 */
@@ -94,7 +90,7 @@ struct iwl4965_scale_tbl_info {
94 u8 is_dup; /* 1 = duplicated data streams */ 90 u8 is_dup; /* 1 = duplicated data streams */
95 u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */ 91 u8 action; /* change modulation; IWL_[LEGACY/SISO/MIMO]_SWITCH_* */
96 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ 92 s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
97 struct iwl4965_rate current_rate; /* rate_n_flags, uCode API format */ 93 u32 current_rate; /* rate_n_flags, uCode API format */
98 struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ 94 struct iwl4965_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
99}; 95};
100 96
@@ -144,7 +140,7 @@ struct iwl4965_lq_sta {
144 140
145 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ 141 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
146 u32 supp_rates; 142 u32 supp_rates;
147 u16 active_rate; 143 u16 active_legacy_rate;
148 u16 active_siso_rate; 144 u16 active_siso_rate;
149 u16 active_mimo2_rate; 145 u16 active_mimo2_rate;
150 u16 active_mimo3_rate; 146 u16 active_mimo3_rate;
@@ -162,7 +158,7 @@ struct iwl4965_lq_sta {
162#ifdef CONFIG_IWL4965_HT 158#ifdef CONFIG_IWL4965_HT
163 struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file; 159 struct dentry *rs_sta_dbgfs_tx_agg_tid_en_file;
164#endif 160#endif
165 struct iwl4965_rate dbg_fixed; 161 u32 dbg_fixed_rate;
166 struct iwl_priv *drv; 162 struct iwl_priv *drv;
167#endif 163#endif
168}; 164};
@@ -173,16 +169,16 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
173 struct sta_info *sta); 169 struct sta_info *sta);
174static void rs_fill_link_cmd(const struct iwl_priv *priv, 170static void rs_fill_link_cmd(const struct iwl_priv *priv,
175 struct iwl4965_lq_sta *lq_sta, 171 struct iwl4965_lq_sta *lq_sta,
176 struct iwl4965_rate *tx_mcs, 172 u32 rate_n_flags,
177 struct iwl_link_quality_cmd *tbl); 173 struct iwl_link_quality_cmd *tbl);
178 174
179 175
180#ifdef CONFIG_MAC80211_DEBUGFS 176#ifdef CONFIG_MAC80211_DEBUGFS
181static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, 177static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
182 struct iwl4965_rate *mcs, int index); 178 u32 *rate_n_flags, int index);
183#else 179#else
184static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, 180static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
185 struct iwl4965_rate *mcs, int index) 181 u32 *rate_n_flags, int index)
186{} 182{}
187#endif 183#endif
188 184
@@ -232,7 +228,7 @@ static s32 expected_tpt_mimo40MHzSGI[IWL_RATE_COUNT] = {
232 0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293 228 0, 0, 0, 0, 131, 131, 191, 222, 242, 270, 284, 289, 293
233}; 229};
234 230
235static inline u8 iwl4965_rate_get_rate(u32 rate_n_flags) 231static inline u8 rs_extract_rate(u32 rate_n_flags)
236{ 232{
237 return (u8)(rate_n_flags & 0xFF); 233 return (u8)(rate_n_flags & 0xFF);
238} 234}
@@ -376,11 +372,11 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
376 372
377#endif /* CONFIG_IWLWIFI_HT */ 373#endif /* CONFIG_IWLWIFI_HT */
378 374
379static inline int get_num_of_ant_from_mcs(u32 mcs) 375static inline int get_num_of_ant_from_rate(u32 rate_n_flags)
380{ 376{
381 return (!!(mcs & RATE_MCS_ANT_A_MSK) + 377 return (!!(rate_n_flags & RATE_MCS_ANT_A_MSK) +
382 !!(mcs & RATE_MCS_ANT_B_MSK) + 378 !!(rate_n_flags & RATE_MCS_ANT_B_MSK) +
383 !!(mcs & RATE_MCS_ANT_C_MSK)); 379 !!(rate_n_flags & RATE_MCS_ANT_C_MSK));
384} 380}
385 381
386/** 382/**
@@ -395,8 +391,7 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
395 int successes) 391 int successes)
396{ 392{
397 struct iwl4965_rate_scale_data *window = NULL; 393 struct iwl4965_rate_scale_data *window = NULL;
398 u64 mask; 394 static const u64 mask = (((u64)1) << (IWL_RATE_MAX_WINDOW - 1));
399 u8 win_size = IWL_RATE_MAX_WINDOW;
400 s32 fail_count; 395 s32 fail_count;
401 396
402 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT) 397 if (scale_index < 0 || scale_index >= IWL_RATE_COUNT)
@@ -414,14 +409,14 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
414 * we keep these bitmaps!). 409 * we keep these bitmaps!).
415 */ 410 */
416 while (retries > 0) { 411 while (retries > 0) {
417 if (window->counter >= win_size) { 412 if (window->counter >= IWL_RATE_MAX_WINDOW) {
418 window->counter = win_size - 1; 413
419 mask = 1; 414 /* remove earliest */
420 mask = (mask << (win_size - 1)); 415 window->counter = IWL_RATE_MAX_WINDOW - 1;
416
421 if (window->data & mask) { 417 if (window->data & mask) {
422 window->data &= ~mask; 418 window->data &= ~mask;
423 window->success_counter = 419 window->success_counter--;
424 window->success_counter - 1;
425 } 420 }
426 } 421 }
427 422
@@ -431,10 +426,9 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
431 /* Shift bitmap by one frame (throw away oldest history), 426 /* Shift bitmap by one frame (throw away oldest history),
432 * OR in "1", and increment "success" if this 427 * OR in "1", and increment "success" if this
433 * frame was successful. */ 428 * frame was successful. */
434 mask = window->data; 429 window->data <<= 1;;
435 window->data = (mask << 1);
436 if (successes > 0) { 430 if (successes > 0) {
437 window->success_counter = window->success_counter + 1; 431 window->success_counter++;
438 window->data |= 0x1; 432 window->data |= 0x1;
439 successes--; 433 successes--;
440 } 434 }
@@ -467,70 +461,72 @@ static int rs_collect_tx_data(struct iwl4965_rate_scale_data *windows,
467/* 461/*
468 * Fill uCode API rate_n_flags field, based on "search" or "active" table. 462 * Fill uCode API rate_n_flags field, based on "search" or "active" table.
469 */ 463 */
470static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate, 464/* FIXME:RS:remove this function and put the flags statically in the table */
471 struct iwl4965_scale_tbl_info *tbl, 465static u32 rate_n_flags_from_tbl(struct iwl4965_scale_tbl_info *tbl,
472 int index, u8 use_green) 466 int index, u8 use_green)
473{ 467{
468 u32 rate_n_flags = 0;
469
474 if (is_legacy(tbl->lq_type)) { 470 if (is_legacy(tbl->lq_type)) {
475 mcs_rate->rate_n_flags = iwl4965_rates[index].plcp; 471 rate_n_flags = iwl4965_rates[index].plcp;
476 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) 472 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
477 mcs_rate->rate_n_flags |= RATE_MCS_CCK_MSK; 473 rate_n_flags |= RATE_MCS_CCK_MSK;
478 474
479 } else if (is_Ht(tbl->lq_type)) { 475 } else if (is_Ht(tbl->lq_type)) {
480 if (index > IWL_LAST_OFDM_RATE) { 476 if (index > IWL_LAST_OFDM_RATE) {
481 IWL_ERROR("invalid HT rate index %d\n", index); 477 IWL_ERROR("invalid HT rate index %d\n", index);
482 index = IWL_LAST_OFDM_RATE; 478 index = IWL_LAST_OFDM_RATE;
483 } 479 }
484 mcs_rate->rate_n_flags = RATE_MCS_HT_MSK; 480 rate_n_flags = RATE_MCS_HT_MSK;
485 481
486 if (is_siso(tbl->lq_type)) 482 if (is_siso(tbl->lq_type))
487 mcs_rate->rate_n_flags |= 483 rate_n_flags |= iwl4965_rates[index].plcp_siso;
488 iwl4965_rates[index].plcp_siso;
489 else if (is_mimo2(tbl->lq_type)) 484 else if (is_mimo2(tbl->lq_type))
490 mcs_rate->rate_n_flags |= 485 rate_n_flags |= iwl4965_rates[index].plcp_mimo2;
491 iwl4965_rates[index].plcp_mimo2;
492 else 486 else
493 mcs_rate->rate_n_flags |= 487 rate_n_flags |= iwl4965_rates[index].plcp_mimo3;
494 iwl4965_rates[index].plcp_mimo3;
495 } else { 488 } else {
496 IWL_ERROR("Invalid tbl->lq_type %d\n", tbl->lq_type); 489 IWL_ERROR("Invalid tbl->lq_type %d\n", tbl->lq_type);
497 } 490 }
498 491
499 mcs_rate->rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) & 492 rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) &
500 RATE_MCS_ANT_ABC_MSK); 493 RATE_MCS_ANT_ABC_MSK);
501 494
502 if (is_legacy(tbl->lq_type)) 495 if (is_Ht(tbl->lq_type)) {
503 return; 496 if (tbl->is_fat) {
504 497 if (tbl->is_dup)
505 if (tbl->is_fat) { 498 rate_n_flags |= RATE_MCS_DUP_MSK;
506 if (tbl->is_dup) 499 else
507 mcs_rate->rate_n_flags |= RATE_MCS_DUP_MSK; 500 rate_n_flags |= RATE_MCS_FAT_MSK;
508 else 501 }
509 mcs_rate->rate_n_flags |= RATE_MCS_FAT_MSK; 502 if (tbl->is_SGI)
510 } 503 rate_n_flags |= RATE_MCS_SGI_MSK;
511 if (tbl->is_SGI) 504
512 mcs_rate->rate_n_flags |= RATE_MCS_SGI_MSK; 505 if (use_green) {
513 506 rate_n_flags |= RATE_MCS_GF_MSK;
514 if (use_green) { 507 if (is_siso(tbl->lq_type) && tbl->is_SGI) {
515 mcs_rate->rate_n_flags |= RATE_MCS_GF_MSK; 508 rate_n_flags &= ~RATE_MCS_SGI_MSK;
516 if (is_siso(tbl->lq_type)) 509 IWL_ERROR("GF was set with SGI:SISO\n");
517 mcs_rate->rate_n_flags &= ~RATE_MCS_SGI_MSK; 510 }
511 }
518 } 512 }
513 return rate_n_flags;
519} 514}
520 515
521/* 516/*
522 * Interpret uCode API's rate_n_flags format, 517 * Interpret uCode API's rate_n_flags format,
523 * fill "search" or "active" tx mode table. 518 * fill "search" or "active" tx mode table.
524 */ 519 */
525static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, 520static int rs_get_tbl_info_from_mcs(const u32 rate_n_flags,
526 enum ieee80211_band band, 521 enum ieee80211_band band,
527 struct iwl4965_scale_tbl_info *tbl, 522 struct iwl4965_scale_tbl_info *tbl,
528 int *rate_idx) 523 int *rate_idx)
529{ 524{
530 u32 ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_ABC_MSK); 525 u32 ant_msk = (rate_n_flags & RATE_MCS_ANT_ABC_MSK);
531 u8 num_of_ant = get_num_of_ant_from_mcs(ant_msk); 526 u8 num_of_ant = get_num_of_ant_from_rate(rate_n_flags);
527 u8 mcs;
532 528
533 *rate_idx = iwl4965_hwrate_to_plcp_idx(mcs_rate->rate_n_flags); 529 *rate_idx = iwl4965_hwrate_to_plcp_idx(rate_n_flags);
534 530
535 if (*rate_idx == IWL_RATE_INVALID) { 531 if (*rate_idx == IWL_RATE_INVALID) {
536 *rate_idx = -1; 532 *rate_idx = -1;
@@ -543,7 +539,7 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
543 tbl->lq_type = LQ_NONE; 539 tbl->lq_type = LQ_NONE;
544 540
545 /* legacy rate format */ 541 /* legacy rate format */
546 if (!(mcs_rate->rate_n_flags & RATE_MCS_HT_MSK)) { 542 if (!(rate_n_flags & RATE_MCS_HT_MSK)) {
547 if (num_of_ant == 1) { 543 if (num_of_ant == 1) {
548 if (band == IEEE80211_BAND_5GHZ) 544 if (band == IEEE80211_BAND_5GHZ)
549 tbl->lq_type = LQ_A; 545 tbl->lq_type = LQ_A;
@@ -552,25 +548,24 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
552 } 548 }
553 /* HT rate format */ 549 /* HT rate format */
554 } else { 550 } else {
555 if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK) 551 if (rate_n_flags & RATE_MCS_SGI_MSK)
556 tbl->is_SGI = 1; 552 tbl->is_SGI = 1;
557 553
558 if ((mcs_rate->rate_n_flags & RATE_MCS_FAT_MSK) || 554 if ((rate_n_flags & RATE_MCS_FAT_MSK) ||
559 (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK)) 555 (rate_n_flags & RATE_MCS_DUP_MSK))
560 tbl->is_fat = 1; 556 tbl->is_fat = 1;
561 557
562 if (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK) 558 if (rate_n_flags & RATE_MCS_DUP_MSK)
563 tbl->is_dup = 1; 559 tbl->is_dup = 1;
564 560
565 /* SISO */ 561 mcs = rs_extract_rate(rate_n_flags);
566 if (iwl4965_rate_get_rate(mcs_rate->rate_n_flags)
567 <= IWL_RATE_SISO_60M_PLCP) {
568 562
563 /* SISO */
564 if (mcs <= IWL_RATE_SISO_60M_PLCP) {
569 if (num_of_ant == 1) 565 if (num_of_ant == 1)
570 tbl->lq_type = LQ_SISO; /*else NONE*/ 566 tbl->lq_type = LQ_SISO; /*else NONE*/
571 /* MIMO2 */ 567 /* MIMO2 */
572 } else if (iwl4965_rate_get_rate(mcs_rate->rate_n_flags) 568 } else if (mcs <= IWL_RATE_MIMO2_60M_PLCP) {
573 <= IWL_RATE_MIMO2_60M_PLCP) {
574 if (num_of_ant == 2) 569 if (num_of_ant == 2)
575 tbl->lq_type = LQ_MIMO2; 570 tbl->lq_type = LQ_MIMO2;
576 /* MIMO3 */ 571 /* MIMO3 */
@@ -582,13 +577,14 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
582 return 0; 577 return 0;
583} 578}
584/* FIXME:RS: need to toggle also ANT_C, and also AB,AC,BC */ 579/* FIXME:RS: need to toggle also ANT_C, and also AB,AC,BC */
585static inline void rs_toggle_antenna(struct iwl4965_rate *new_rate, 580static inline void rs_toggle_antenna(u32 *rate_n_flags,
586 struct iwl4965_scale_tbl_info *tbl) 581 struct iwl4965_scale_tbl_info *tbl)
587{ 582{
588 tbl->ant_type ^= ANT_AB; 583 tbl->ant_type ^= ANT_AB;
589 new_rate->rate_n_flags ^= (RATE_MCS_ANT_A_MSK|RATE_MCS_ANT_B_MSK); 584 *rate_n_flags ^= (RATE_MCS_ANT_A_MSK|RATE_MCS_ANT_B_MSK);
590} 585}
591 586
587/* FIXME:RS: in 4965 we don't use greenfield at all */
592static inline u8 rs_use_green(struct iwl_priv *priv, 588static inline u8 rs_use_green(struct iwl_priv *priv,
593 struct ieee80211_conf *conf) 589 struct ieee80211_conf *conf)
594{ 590{
@@ -596,8 +592,9 @@ static inline u8 rs_use_green(struct iwl_priv *priv,
596 return ((conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) && 592 return ((conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) &&
597 priv->current_ht_config.is_green_field && 593 priv->current_ht_config.is_green_field &&
598 !priv->current_ht_config.non_GF_STA_present); 594 !priv->current_ht_config.non_GF_STA_present);
599#endif /* CONFIG_IWL4965_HT */ 595#else
600 return 0; 596 return 0;
597#endif /* CONFIG_IWL4965_HT */
601} 598}
602 599
603/** 600/**
@@ -613,7 +610,7 @@ static void rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta,
613 u16 *data_rate) 610 u16 *data_rate)
614{ 611{
615 if (is_legacy(rate_type)) 612 if (is_legacy(rate_type))
616 *data_rate = lq_sta->active_rate; 613 *data_rate = lq_sta->active_legacy_rate;
617 else { 614 else {
618 if (is_siso(rate_type)) 615 if (is_siso(rate_type))
619 *data_rate = lq_sta->active_siso_rate; 616 *data_rate = lq_sta->active_siso_rate;
@@ -684,9 +681,9 @@ static u16 rs_get_adjacent_rate(u8 index, u16 rate_mask, int rate_type)
684 return (high << 8) | low; 681 return (high << 8) | low;
685} 682}
686 683
687static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, 684static u32 rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
688 struct iwl4965_scale_tbl_info *tbl, u8 scale_index, 685 struct iwl4965_scale_tbl_info *tbl, u8 scale_index,
689 u8 ht_possible, struct iwl4965_rate *mcs_rate) 686 u8 ht_possible)
690{ 687{
691 s32 low; 688 s32 low;
692 u16 rate_mask; 689 u16 rate_mask;
@@ -726,17 +723,18 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
726 723
727 /* If we switched from HT to legacy, check current rate */ 724 /* If we switched from HT to legacy, check current rate */
728 if (switch_to_legacy && (rate_mask & (1 << scale_index))) { 725 if (switch_to_legacy && (rate_mask & (1 << scale_index))) {
729 rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green); 726 low = scale_index;
730 return; 727 goto out;
731 } 728 }
732 729
733 high_low = rs_get_adjacent_rate(scale_index, rate_mask, tbl->lq_type); 730 high_low = rs_get_adjacent_rate(scale_index, rate_mask, tbl->lq_type);
734 low = high_low & 0xff; 731 low = high_low & 0xff;
735 732
736 if (low != IWL_RATE_INVALID) 733 if (low == IWL_RATE_INVALID)
737 rs_mcs_from_tbl(mcs_rate, tbl, low, is_green); 734 low = scale_index;
738 else 735
739 rs_mcs_from_tbl(mcs_rate, tbl, scale_index, is_green); 736out:
737 return rate_n_flags_from_tbl(tbl, low, is_green);
740} 738}
741 739
742/* 740/*
@@ -758,7 +756,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
758 struct ieee80211_hw *hw = local_to_hw(local); 756 struct ieee80211_hw *hw = local_to_hw(local);
759 struct iwl4965_rate_scale_data *window = NULL; 757 struct iwl4965_rate_scale_data *window = NULL;
760 struct iwl4965_rate_scale_data *search_win = NULL; 758 struct iwl4965_rate_scale_data *search_win = NULL;
761 struct iwl4965_rate tx_mcs; 759 u32 tx_rate;
762 struct iwl4965_scale_tbl_info tbl_type; 760 struct iwl4965_scale_tbl_info tbl_type;
763 struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl; 761 struct iwl4965_scale_tbl_info *curr_tbl, *search_tbl;
764 u8 active_index = 0; 762 u8 active_index = 0;
@@ -817,8 +815,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
817 * to check "search" mode, or a prior "search" mode after we've moved 815 * to check "search" mode, or a prior "search" mode after we've moved
818 * to a new "search" mode (which might become the new "active" mode). 816 * to a new "search" mode (which might become the new "active" mode).
819 */ 817 */
820 tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[0].rate_n_flags); 818 tx_rate = le32_to_cpu(table->rs_table[0].rate_n_flags);
821 rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, &tbl_type, &rs_index); 819 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);
822 if (priv->band == IEEE80211_BAND_5GHZ) 820 if (priv->band == IEEE80211_BAND_5GHZ)
823 rs_index -= IWL_FIRST_OFDM_RATE; 821 rs_index -= IWL_FIRST_OFDM_RATE;
824 822
@@ -830,14 +828,13 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
830 (tbl_type.is_dup ^ 828 (tbl_type.is_dup ^
831 !!(tx_resp->control.flags & IEEE80211_TXCTL_DUP_DATA)) || 829 !!(tx_resp->control.flags & IEEE80211_TXCTL_DUP_DATA)) ||
832 (tbl_type.ant_type ^ tx_resp->control.antenna_sel_tx) || 830 (tbl_type.ant_type ^ tx_resp->control.antenna_sel_tx) ||
833 (!!(tx_mcs.rate_n_flags & RATE_MCS_HT_MSK) ^ 831 (!!(tx_rate & RATE_MCS_HT_MSK) ^
834 !!(tx_resp->control.flags & IEEE80211_TXCTL_OFDM_HT)) || 832 !!(tx_resp->control.flags & IEEE80211_TXCTL_OFDM_HT)) ||
835 (!!(tx_mcs.rate_n_flags & RATE_MCS_GF_MSK) ^ 833 (!!(tx_rate & RATE_MCS_GF_MSK) ^
836 !!(tx_resp->control.flags & IEEE80211_TXCTL_GREEN_FIELD)) || 834 !!(tx_resp->control.flags & IEEE80211_TXCTL_GREEN_FIELD)) ||
837 (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate != 835 (hw->wiphy->bands[priv->band]->bitrates[rs_index].bitrate !=
838 tx_resp->control.tx_rate->bitrate)) { 836 tx_resp->control.tx_rate->bitrate)) {
839 IWL_DEBUG_RATE("initial rate does not match 0x%x\n", 837 IWL_DEBUG_RATE("initial rate does not match 0x%x\n", tx_rate);
840 tx_mcs.rate_n_flags);
841 goto out; 838 goto out;
842 } 839 }
843 840
@@ -845,9 +842,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
845 while (retries) { 842 while (retries) {
846 /* Look up the rate and other info used for each tx attempt. 843 /* Look up the rate and other info used for each tx attempt.
847 * Each tx attempt steps one entry deeper in the rate table. */ 844 * Each tx attempt steps one entry deeper in the rate table. */
848 tx_mcs.rate_n_flags = 845 tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags);
849 le32_to_cpu(table->rs_table[index].rate_n_flags); 846 rs_get_tbl_info_from_mcs(tx_rate, priv->band,
850 rs_get_tbl_info_from_mcs(&tx_mcs, priv->band,
851 &tbl_type, &rs_index); 847 &tbl_type, &rs_index);
852 848
853 /* If type matches "search" table, 849 /* If type matches "search" table,
@@ -887,8 +883,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
887 * if Tx was successful first try, use original rate, 883 * if Tx was successful first try, use original rate,
888 * else look up the rate that was, finally, successful. 884 * else look up the rate that was, finally, successful.
889 */ 885 */
890 tx_mcs.rate_n_flags = le32_to_cpu(table->rs_table[index].rate_n_flags); 886 tx_rate = le32_to_cpu(table->rs_table[index].rate_n_flags);
891 rs_get_tbl_info_from_mcs(&tx_mcs, priv->band, &tbl_type, &rs_index); 887 rs_get_tbl_info_from_mcs(tx_rate, priv->band, &tbl_type, &rs_index);
892 888
893 /* Update frame history window with "success" if Tx got ACKed ... */ 889 /* Update frame history window with "success" if Tx got ACKed ... */
894 if (tx_resp->flags & IEEE80211_TX_STATUS_ACK) 890 if (tx_resp->flags & IEEE80211_TX_STATUS_ACK)
@@ -1158,11 +1154,6 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
1158 !sta->ht_info.ht_supported) 1154 !sta->ht_info.ht_supported)
1159 return -1; 1155 return -1;
1160 1156
1161 IWL_DEBUG_HT("LQ: try to switch to MIMO\n");
1162 tbl->lq_type = LQ_MIMO2;
1163 rs_get_supported_rates(lq_sta, NULL, tbl->lq_type,
1164 &rate_mask);
1165
1166 if (priv->current_ht_config.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC) 1157 if (priv->current_ht_config.tx_mimo_ps_mode == IWL_MIMO_PS_STATIC)
1167 return -1; 1158 return -1;
1168 1159
@@ -1170,14 +1161,20 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
1170 if (!rs_is_both_ant_supp(priv->hw_params.valid_tx_ant)) 1161 if (!rs_is_both_ant_supp(priv->hw_params.valid_tx_ant))
1171 return -1; 1162 return -1;
1172 1163
1164 IWL_DEBUG_HT("LQ: try to switch to MIMO2\n");
1165
1166 tbl->lq_type = LQ_MIMO2;
1173 tbl->is_dup = lq_sta->is_dup; 1167 tbl->is_dup = lq_sta->is_dup;
1174 tbl->action = 0; 1168 tbl->action = 0;
1169 rate_mask = lq_sta->active_mimo2_rate;
1170
1175 if (priv->current_ht_config.supported_chan_width 1171 if (priv->current_ht_config.supported_chan_width
1176 == IWL_CHANNEL_WIDTH_40MHZ) 1172 == IWL_CHANNEL_WIDTH_40MHZ)
1177 tbl->is_fat = 1; 1173 tbl->is_fat = 1;
1178 else 1174 else
1179 tbl->is_fat = 0; 1175 tbl->is_fat = 0;
1180 1176
1177 /* FIXME: - don't toggle SGI here
1181 if (tbl->is_fat) { 1178 if (tbl->is_fat) {
1182 if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY) 1179 if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
1183 tbl->is_SGI = 1; 1180 tbl->is_SGI = 1;
@@ -1187,18 +1184,23 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv,
1187 tbl->is_SGI = 1; 1184 tbl->is_SGI = 1;
1188 else 1185 else
1189 tbl->is_SGI = 0; 1186 tbl->is_SGI = 0;
1187 */
1190 1188
1191 rs_get_expected_tpt_table(lq_sta, tbl); 1189 rs_get_expected_tpt_table(lq_sta, tbl);
1192 1190
1193 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index, index); 1191 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index, index);
1194 1192
1195 IWL_DEBUG_HT("LQ: MIMO best rate %d mask %X\n", rate, rate_mask); 1193 IWL_DEBUG_HT("LQ: MIMO2 best rate %d mask %X\n", rate, rate_mask);
1196 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) 1194
1195 if ((rate == IWL_RATE_INVALID) || !((1 << rate) & rate_mask)) {
1196 IWL_DEBUG_HT("Can't switch with index %d rate mask %x\n",
1197 rate, rate_mask);
1197 return -1; 1198 return -1;
1198 rs_mcs_from_tbl(&tbl->current_rate, tbl, rate, is_green); 1199 }
1200 tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green);
1199 1201
1200 IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n", 1202 IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n",
1201 tbl->current_rate.rate_n_flags, is_green); 1203 tbl->current_rate, is_green);
1202 return 0; 1204 return 0;
1203} 1205}
1204#else 1206#else
@@ -1226,16 +1228,16 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
1226 u8 is_green = lq_sta->is_green; 1228 u8 is_green = lq_sta->is_green;
1227 s32 rate; 1229 s32 rate;
1228 1230
1229 IWL_DEBUG_HT("LQ: try to switch to SISO\n");
1230 if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) || 1231 if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) ||
1231 !sta->ht_info.ht_supported) 1232 !sta->ht_info.ht_supported)
1232 return -1; 1233 return -1;
1233 1234
1235 IWL_DEBUG_HT("LQ: try to switch to SISO\n");
1236
1234 tbl->is_dup = lq_sta->is_dup; 1237 tbl->is_dup = lq_sta->is_dup;
1235 tbl->lq_type = LQ_SISO; 1238 tbl->lq_type = LQ_SISO;
1236 tbl->action = 0; 1239 tbl->action = 0;
1237 rs_get_supported_rates(lq_sta, NULL, tbl->lq_type, 1240 rate_mask = lq_sta->active_siso_rate;
1238 &rate_mask);
1239 1241
1240 if (priv->current_ht_config.supported_chan_width 1242 if (priv->current_ht_config.supported_chan_width
1241 == IWL_CHANNEL_WIDTH_40MHZ) 1243 == IWL_CHANNEL_WIDTH_40MHZ)
@@ -1243,6 +1245,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
1243 else 1245 else
1244 tbl->is_fat = 0; 1246 tbl->is_fat = 0;
1245 1247
1248 /* FIXME: - don't toggle SGI here
1246 if (tbl->is_fat) { 1249 if (tbl->is_fat) {
1247 if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY) 1250 if (priv->current_ht_config.sgf & HT_SHORT_GI_40MHZ_ONLY)
1248 tbl->is_SGI = 1; 1251 tbl->is_SGI = 1;
@@ -1252,9 +1255,10 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
1252 tbl->is_SGI = 1; 1255 tbl->is_SGI = 1;
1253 else 1256 else
1254 tbl->is_SGI = 0; 1257 tbl->is_SGI = 0;
1258 */
1255 1259
1256 if (is_green) 1260 if (is_green)
1257 tbl->is_SGI = 0; 1261 tbl->is_SGI = 0; /*11n spec: no SGI in SISO+Greenfield*/
1258 1262
1259 rs_get_expected_tpt_table(lq_sta, tbl); 1263 rs_get_expected_tpt_table(lq_sta, tbl);
1260 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index, index); 1264 rate = rs_get_best_rate(priv, lq_sta, tbl, rate_mask, index, index);
@@ -1265,9 +1269,9 @@ static int rs_switch_to_siso(struct iwl_priv *priv,
1265 rate, rate_mask); 1269 rate, rate_mask);
1266 return -1; 1270 return -1;
1267 } 1271 }
1268 rs_mcs_from_tbl(&tbl->current_rate, tbl, rate, is_green); 1272 tbl->current_rate = rate_n_flags_from_tbl(tbl, rate, is_green);
1269 IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n", 1273 IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n",
1270 tbl->current_rate.rate_n_flags, is_green); 1274 tbl->current_rate, is_green);
1271 return 0; 1275 return 0;
1272#else 1276#else
1273 return -1; 1277 return -1;
@@ -1298,12 +1302,13 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1298 for (; ;) { 1302 for (; ;) {
1299 switch (tbl->action) { 1303 switch (tbl->action) {
1300 case IWL_LEGACY_SWITCH_ANTENNA: 1304 case IWL_LEGACY_SWITCH_ANTENNA:
1301 IWL_DEBUG_HT("LQ Legacy switch Antenna\n"); 1305 IWL_DEBUG_HT("LQ Legacy toggle Antenna\n");
1302 1306
1303 search_tbl->lq_type = LQ_NONE; 1307 search_tbl->lq_type = LQ_NONE;
1304 lq_sta->action_counter++; 1308 lq_sta->action_counter++;
1305 1309
1306 /* Don't change antenna if success has been great */ 1310 /* Don't change antenna if success has been great */
1311 /*FIXME:RS:not sure this is really needed*/
1307 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1312 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1308 break; 1313 break;
1309 1314
@@ -1315,7 +1320,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1315 /* Set up search table to try other antenna */ 1320 /* Set up search table to try other antenna */
1316 memcpy(search_tbl, tbl, sz); 1321 memcpy(search_tbl, tbl, sz);
1317 1322
1318 rs_toggle_antenna(&(search_tbl->current_rate), 1323 rs_toggle_antenna(&search_tbl->current_rate,
1319 search_tbl); 1324 search_tbl);
1320 rs_get_expected_tpt_table(lq_sta, search_tbl); 1325 rs_get_expected_tpt_table(lq_sta, search_tbl);
1321 lq_sta->search_better_tbl = 1; 1326 lq_sta->search_better_tbl = 1;
@@ -1326,9 +1331,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1326 1331
1327 /* Set up search table to try SISO */ 1332 /* Set up search table to try SISO */
1328 memcpy(search_tbl, tbl, sz); 1333 memcpy(search_tbl, tbl, sz);
1329 search_tbl->lq_type = LQ_SISO;
1330 search_tbl->is_SGI = 0; 1334 search_tbl->is_SGI = 0;
1331 search_tbl->is_fat = 0;
1332 ret = rs_switch_to_siso(priv, lq_sta, conf, sta, 1335 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
1333 search_tbl, index); 1336 search_tbl, index);
1334 if (!ret) { 1337 if (!ret) {
@@ -1339,13 +1342,11 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1339 1342
1340 break; 1343 break;
1341 case IWL_LEGACY_SWITCH_MIMO2: 1344 case IWL_LEGACY_SWITCH_MIMO2:
1342 IWL_DEBUG_HT("LQ: Legacy switch MIMO\n"); 1345 IWL_DEBUG_HT("LQ: Legacy switch to MIMO2\n");
1343 1346
1344 /* Set up search table to try MIMO */ 1347 /* Set up search table to try MIMO */
1345 memcpy(search_tbl, tbl, sz); 1348 memcpy(search_tbl, tbl, sz);
1346 search_tbl->lq_type = LQ_MIMO2;
1347 search_tbl->is_SGI = 0; 1349 search_tbl->is_SGI = 0;
1348 search_tbl->is_fat = 0;
1349 search_tbl->ant_type = ANT_AB;/*FIXME:RS*/ 1350 search_tbl->ant_type = ANT_AB;/*FIXME:RS*/
1350 /*FIXME:RS:need to check ant validity*/ 1351 /*FIXME:RS:need to check ant validity*/
1351 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta, 1352 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
@@ -1400,8 +1401,8 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1400 lq_sta->action_counter++; 1401 lq_sta->action_counter++;
1401 switch (tbl->action) { 1402 switch (tbl->action) {
1402 case IWL_SISO_SWITCH_ANTENNA: 1403 case IWL_SISO_SWITCH_ANTENNA:
1403 IWL_DEBUG_HT("LQ: SISO SWITCH ANTENNA SISO\n"); 1404 IWL_DEBUG_HT("LQ: SISO toggle Antenna\n");
1404 search_tbl->lq_type = LQ_NONE; 1405 /*FIXME:RS: is this really needed for SISO?*/
1405 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1406 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1406 break; 1407 break;
1407 if (!rs_is_other_ant_connected(valid_tx_ant, 1408 if (!rs_is_other_ant_connected(valid_tx_ant,
@@ -1409,19 +1410,16 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1409 break; 1410 break;
1410 1411
1411 memcpy(search_tbl, tbl, sz); 1412 memcpy(search_tbl, tbl, sz);
1412 search_tbl->action = IWL_SISO_SWITCH_MIMO2; 1413 rs_toggle_antenna(&search_tbl->current_rate,
1413 rs_toggle_antenna(&(search_tbl->current_rate),
1414 search_tbl); 1414 search_tbl);
1415 lq_sta->search_better_tbl = 1; 1415 lq_sta->search_better_tbl = 1;
1416 1416
1417 goto out; 1417 goto out;
1418 1418
1419 case IWL_SISO_SWITCH_MIMO2: 1419 case IWL_SISO_SWITCH_MIMO2:
1420 IWL_DEBUG_HT("LQ: SISO SWITCH TO MIMO2 FROM SISO\n"); 1420 IWL_DEBUG_HT("LQ: SISO switch to MIMO\n");
1421 memcpy(search_tbl, tbl, sz); 1421 memcpy(search_tbl, tbl, sz);
1422 search_tbl->lq_type = LQ_MIMO2;
1423 search_tbl->is_SGI = 0; 1422 search_tbl->is_SGI = 0;
1424 search_tbl->is_fat = 0;
1425 search_tbl->ant_type = ANT_AB; /*FIXME:RS*/ 1423 search_tbl->ant_type = ANT_AB; /*FIXME:RS*/
1426 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta, 1424 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
1427 search_tbl, index); 1425 search_tbl, index);
@@ -1431,29 +1429,25 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1431 } 1429 }
1432 break; 1430 break;
1433 case IWL_SISO_SWITCH_GI: 1431 case IWL_SISO_SWITCH_GI:
1434 IWL_DEBUG_HT("LQ: SISO SWITCH TO GI\n"); 1432 IWL_DEBUG_HT("LQ: SISO toggle SGI/NGI\n");
1435 1433
1436 memcpy(search_tbl, tbl, sz); 1434 memcpy(search_tbl, tbl, sz);
1437 search_tbl->action = 0; 1435 if (is_green) {
1438 if (search_tbl->is_SGI) 1436 if (!tbl->is_SGI)
1439 search_tbl->is_SGI = 0; 1437 break;
1440 else if (!is_green) 1438 else
1441 search_tbl->is_SGI = 1; 1439 IWL_ERROR("SGI was set in GF+SISO\n");
1442 else
1443 break;
1444 lq_sta->search_better_tbl = 1;
1445 if ((tbl->lq_type == LQ_SISO) &&
1446 (tbl->is_SGI)) {
1447 s32 tpt = lq_sta->last_tpt / 100;
1448 if (((!tbl->is_fat) &&
1449 (tpt >= expected_tpt_siso20MHz[index])) ||
1450 ((tbl->is_fat) &&
1451 (tpt >= expected_tpt_siso40MHz[index])))
1452 lq_sta->search_better_tbl = 0;
1453 } 1440 }
1441 search_tbl->is_SGI = !tbl->is_SGI;
1454 rs_get_expected_tpt_table(lq_sta, search_tbl); 1442 rs_get_expected_tpt_table(lq_sta, search_tbl);
1455 rs_mcs_from_tbl(&search_tbl->current_rate, 1443 if (tbl->is_SGI) {
1456 search_tbl, index, is_green); 1444 s32 tpt = lq_sta->last_tpt / 100;
1445 if (tpt >= search_tbl->expected_tpt[index])
1446 break;
1447 }
1448 search_tbl->current_rate = rate_n_flags_from_tbl(
1449 search_tbl, index, is_green);
1450 lq_sta->search_better_tbl = 1;
1457 goto out; 1451 goto out;
1458 } 1452 }
1459 tbl->action++; 1453 tbl->action++;
@@ -1496,15 +1490,12 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
1496 switch (tbl->action) { 1490 switch (tbl->action) {
1497 case IWL_MIMO_SWITCH_ANTENNA_A: 1491 case IWL_MIMO_SWITCH_ANTENNA_A:
1498 case IWL_MIMO_SWITCH_ANTENNA_B: 1492 case IWL_MIMO_SWITCH_ANTENNA_B:
1499 IWL_DEBUG_HT("LQ: MIMO SWITCH TO SISO\n"); 1493 IWL_DEBUG_HT("LQ: MIMO2 switch to SISO\n");
1500
1501 1494
1502 /* Set up new search table for SISO */ 1495 /* Set up new search table for SISO */
1503 memcpy(search_tbl, tbl, sz); 1496 memcpy(search_tbl, tbl, sz);
1504 search_tbl->lq_type = LQ_SISO; 1497
1505 search_tbl->is_SGI = 0; 1498 /*FIXME:RS:need to check ant validity + C*/
1506 search_tbl->is_fat = 0;
1507 /*FIXME:RS:need to check ant validity + C*/
1508 if (tbl->action == IWL_MIMO_SWITCH_ANTENNA_A) 1499 if (tbl->action == IWL_MIMO_SWITCH_ANTENNA_A)
1509 search_tbl->ant_type = ANT_A; 1500 search_tbl->ant_type = ANT_A;
1510 else 1501 else
@@ -1519,35 +1510,26 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
1519 break; 1510 break;
1520 1511
1521 case IWL_MIMO_SWITCH_GI: 1512 case IWL_MIMO_SWITCH_GI:
1522 IWL_DEBUG_HT("LQ: MIMO SWITCH TO GI\n"); 1513 IWL_DEBUG_HT("LQ: MIMO toggle SGI/NGI\n");
1523 1514
1524 /* Set up new search table for MIMO */ 1515 /* Set up new search table for MIMO */
1525 memcpy(search_tbl, tbl, sz); 1516 memcpy(search_tbl, tbl, sz);
1526 search_tbl->action = 0; 1517 search_tbl->is_SGI = !tbl->is_SGI;
1527 if (search_tbl->is_SGI) 1518 rs_get_expected_tpt_table(lq_sta, search_tbl);
1528 search_tbl->is_SGI = 0;
1529 else
1530 search_tbl->is_SGI = 1;
1531 lq_sta->search_better_tbl = 1;
1532
1533 /* 1519 /*
1534 * If active table already uses the fastest possible 1520 * If active table already uses the fastest possible
1535 * modulation (dual stream with short guard interval), 1521 * modulation (dual stream with short guard interval),
1536 * and it's working well, there's no need to look 1522 * and it's working well, there's no need to look
1537 * for a better type of modulation! 1523 * for a better type of modulation!
1538 */ 1524 */
1539 if ((tbl->lq_type == LQ_MIMO2) && 1525 if (tbl->is_SGI) {
1540 (tbl->is_SGI)) {
1541 s32 tpt = lq_sta->last_tpt / 100; 1526 s32 tpt = lq_sta->last_tpt / 100;
1542 if (((!tbl->is_fat) && 1527 if (tpt >= search_tbl->expected_tpt[index])
1543 (tpt >= expected_tpt_mimo20MHz[index])) || 1528 break;
1544 ((tbl->is_fat) &&
1545 (tpt >= expected_tpt_mimo40MHz[index])))
1546 lq_sta->search_better_tbl = 0;
1547 } 1529 }
1548 rs_get_expected_tpt_table(lq_sta, search_tbl); 1530 search_tbl->current_rate = rate_n_flags_from_tbl(
1549 rs_mcs_from_tbl(&search_tbl->current_rate, 1531 search_tbl, index, is_green);
1550 search_tbl, index, is_green); 1532 lq_sta->search_better_tbl = 1;
1551 goto out; 1533 goto out;
1552 1534
1553 } 1535 }
@@ -1677,7 +1659,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1677 struct iwl4965_lq_sta *lq_sta; 1659 struct iwl4965_lq_sta *lq_sta;
1678 struct iwl4965_scale_tbl_info *tbl, *tbl1; 1660 struct iwl4965_scale_tbl_info *tbl, *tbl1;
1679 u16 rate_scale_index_msk = 0; 1661 u16 rate_scale_index_msk = 0;
1680 struct iwl4965_rate mcs_rate; 1662 u32 rate;
1681 u8 is_green = 0; 1663 u8 is_green = 0;
1682 u8 active_tbl = 0; 1664 u8 active_tbl = 0;
1683 u8 done_search = 0; 1665 u8 done_search = 0;
@@ -1802,8 +1784,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1802 1784
1803 /* Set up new rate table in uCode, if needed */ 1785 /* Set up new rate table in uCode, if needed */
1804 if (update_lq) { 1786 if (update_lq) {
1805 rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); 1787 rate = rate_n_flags_from_tbl(tbl, index, is_green);
1806 rs_fill_link_cmd(priv, lq_sta, &mcs_rate, &lq_sta->lq); 1788 rs_fill_link_cmd(priv, lq_sta, rate, &lq_sta->lq);
1807 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 1789 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
1808 } 1790 }
1809 goto out; 1791 goto out;
@@ -1847,7 +1829,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1847 1829
1848 /* Revert to "active" rate and throughput info */ 1830 /* Revert to "active" rate and throughput info */
1849 index = iwl4965_hwrate_to_plcp_idx( 1831 index = iwl4965_hwrate_to_plcp_idx(
1850 tbl->current_rate.rate_n_flags); 1832 tbl->current_rate);
1851 current_tpt = lq_sta->last_tpt; 1833 current_tpt = lq_sta->last_tpt;
1852 1834
1853 /* Need to set up a new rate table in uCode */ 1835 /* Need to set up a new rate table in uCode */
@@ -1967,8 +1949,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1967 lq_update: 1949 lq_update:
1968 /* Replace uCode's rate table for the destination station. */ 1950 /* Replace uCode's rate table for the destination station. */
1969 if (update_lq) { 1951 if (update_lq) {
1970 rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); 1952 rate = rate_n_flags_from_tbl(tbl, index, is_green);
1971 rs_fill_link_cmd(priv, lq_sta, &mcs_rate, &lq_sta->lq); 1953 rs_fill_link_cmd(priv, lq_sta, rate, &lq_sta->lq);
1972 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 1954 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
1973 } 1955 }
1974 1956
@@ -2003,11 +1985,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2003 1985
2004 /* Use new "search" start rate */ 1986 /* Use new "search" start rate */
2005 index = iwl4965_hwrate_to_plcp_idx( 1987 index = iwl4965_hwrate_to_plcp_idx(
2006 tbl->current_rate.rate_n_flags); 1988 tbl->current_rate);
2007 1989
2008 IWL_DEBUG_HT("Switch current mcs: %X index: %d\n", 1990 IWL_DEBUG_HT("Switch current mcs: %X index: %d\n",
2009 tbl->current_rate.rate_n_flags, index); 1991 tbl->current_rate, index);
2010 rs_fill_link_cmd(priv, lq_sta, &tbl->current_rate, 1992 rs_fill_link_cmd(priv, lq_sta, tbl->current_rate,
2011 &lq_sta->lq); 1993 &lq_sta->lq);
2012 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 1994 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
2013 } 1995 }
@@ -2058,7 +2040,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2058 } 2040 }
2059 2041
2060out: 2042out:
2061 rs_mcs_from_tbl(&tbl->current_rate, tbl, index, is_green); 2043 tbl->current_rate = rate_n_flags_from_tbl(tbl, index, is_green);
2062 i = index; 2044 i = index;
2063 sta->last_txrate_idx = i; 2045 sta->last_txrate_idx = i;
2064 2046
@@ -2084,7 +2066,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2084 u8 active_tbl = 0; 2066 u8 active_tbl = 0;
2085 int rate_idx; 2067 int rate_idx;
2086 u8 use_green = rs_use_green(priv, conf); 2068 u8 use_green = rs_use_green(priv, conf);
2087 struct iwl4965_rate mcs_rate; 2069 u32 rate;
2088 2070
2089 if (!sta || !sta->rate_ctrl_priv) 2071 if (!sta || !sta->rate_ctrl_priv)
2090 goto out; 2072 goto out;
@@ -2107,22 +2089,22 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2107 i = 0; 2089 i = 0;
2108 2090
2109 /* FIXME:RS: This is also wrong in 4965 */ 2091 /* FIXME:RS: This is also wrong in 4965 */
2110 mcs_rate.rate_n_flags = iwl4965_rates[i].plcp ; 2092 rate = iwl4965_rates[i].plcp;
2111 mcs_rate.rate_n_flags |= RATE_MCS_ANT_B_MSK; 2093 rate |= RATE_MCS_ANT_B_MSK;
2112 mcs_rate.rate_n_flags &= ~RATE_MCS_ANT_A_MSK; 2094 rate &= ~RATE_MCS_ANT_A_MSK;
2113 2095
2114 if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE) 2096 if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE)
2115 mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK; 2097 rate |= RATE_MCS_CCK_MSK;
2116 2098
2117 tbl->ant_type = ANT_B; 2099 tbl->ant_type = ANT_B;
2118 rs_get_tbl_info_from_mcs(&mcs_rate, priv->band, tbl, &rate_idx); 2100 rs_get_tbl_info_from_mcs(rate, priv->band, tbl, &rate_idx);
2119 if (!rs_is_ant_connected(priv->hw_params.valid_tx_ant, tbl->ant_type)) 2101 if (!rs_is_ant_connected(priv->hw_params.valid_tx_ant, tbl->ant_type))
2120 rs_toggle_antenna(&mcs_rate, tbl); 2102 rs_toggle_antenna(&rate, tbl);
2121 2103
2122 rs_mcs_from_tbl(&mcs_rate, tbl, rate_idx, use_green); 2104 rate = rate_n_flags_from_tbl(tbl, rate_idx, use_green);
2123 tbl->current_rate.rate_n_flags = mcs_rate.rate_n_flags; 2105 tbl->current_rate = rate;
2124 rs_get_expected_tpt_table(lq_sta, tbl); 2106 rs_get_expected_tpt_table(lq_sta, tbl);
2125 rs_fill_link_cmd(NULL, lq_sta, &mcs_rate, &lq_sta->lq); 2107 rs_fill_link_cmd(NULL, lq_sta, rate, &lq_sta->lq);
2126 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 2108 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
2127 out: 2109 out:
2128 return; 2110 return;
@@ -2275,8 +2257,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
2275 2257
2276 lq_sta->is_dup = 0; 2258 lq_sta->is_dup = 0;
2277 lq_sta->is_green = rs_use_green(priv, conf); 2259 lq_sta->is_green = rs_use_green(priv, conf);
2278 lq_sta->active_rate = priv->active_rate; 2260 lq_sta->active_legacy_rate = priv->active_rate & ~(0x1000);
2279 lq_sta->active_rate &= ~(0x1000);
2280 lq_sta->active_rate_basic = priv->active_rate_basic; 2261 lq_sta->active_rate_basic = priv->active_rate_basic;
2281 lq_sta->band = priv->band; 2262 lq_sta->band = priv->band;
2282#ifdef CONFIG_IWL4965_HT 2263#ifdef CONFIG_IWL4965_HT
@@ -2326,7 +2307,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
2326 2307
2327static void rs_fill_link_cmd(const struct iwl_priv *priv, 2308static void rs_fill_link_cmd(const struct iwl_priv *priv,
2328 struct iwl4965_lq_sta *lq_sta, 2309 struct iwl4965_lq_sta *lq_sta,
2329 struct iwl4965_rate *tx_mcs, 2310 u32 new_rate,
2330 struct iwl_link_quality_cmd *lq_cmd) 2311 struct iwl_link_quality_cmd *lq_cmd)
2331{ 2312{
2332 int index = 0; 2313 int index = 0;
@@ -2334,14 +2315,13 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
2334 int repeat_rate = 0; 2315 int repeat_rate = 0;
2335 u8 ant_toggle_count = 0; 2316 u8 ant_toggle_count = 0;
2336 u8 use_ht_possible = 1; 2317 u8 use_ht_possible = 1;
2337 struct iwl4965_rate new_rate;
2338 struct iwl4965_scale_tbl_info tbl_type = { 0 }; 2318 struct iwl4965_scale_tbl_info tbl_type = { 0 };
2339 2319
2340 /* Override starting rate (index 0) if needed for debug purposes */ 2320 /* Override starting rate (index 0) if needed for debug purposes */
2341 rs_dbgfs_set_mcs(lq_sta, tx_mcs, index); 2321 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
2342 2322
2343 /* Interpret rate_n_flags */ 2323 /* Interpret new_rate (rate_n_flags) */
2344 rs_get_tbl_info_from_mcs(tx_mcs, lq_sta->band, 2324 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band,
2345 &tbl_type, &rate_idx); 2325 &tbl_type, &rate_idx);
2346 2326
2347 /* How many times should we repeat the initial rate? */ 2327 /* How many times should we repeat the initial rate? */
@@ -2355,9 +2335,7 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
2355 is_mimo(tbl_type.lq_type) ? 1 : 0; 2335 is_mimo(tbl_type.lq_type) ? 1 : 0;
2356 2336
2357 /* Fill 1st table entry (index 0) */ 2337 /* Fill 1st table entry (index 0) */
2358 lq_cmd->rs_table[index].rate_n_flags = 2338 lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate);
2359 cpu_to_le32(tx_mcs->rate_n_flags);
2360 new_rate.rate_n_flags = tx_mcs->rate_n_flags;
2361 2339
2362 /*FIXME:RS*/ 2340 /*FIXME:RS*/
2363 if (is_mimo(tbl_type.lq_type) || (tbl_type.ant_type == ANT_A)) 2341 if (is_mimo(tbl_type.lq_type) || (tbl_type.ant_type == ANT_A))
@@ -2393,12 +2371,12 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
2393 2371
2394 /* Fill next table entry */ 2372 /* Fill next table entry */
2395 lq_cmd->rs_table[index].rate_n_flags = 2373 lq_cmd->rs_table[index].rate_n_flags =
2396 cpu_to_le32(new_rate.rate_n_flags); 2374 cpu_to_le32(new_rate);
2397 repeat_rate--; 2375 repeat_rate--;
2398 index++; 2376 index++;
2399 } 2377 }
2400 2378
2401 rs_get_tbl_info_from_mcs(&new_rate, lq_sta->band, &tbl_type, 2379 rs_get_tbl_info_from_mcs(new_rate, lq_sta->band, &tbl_type,
2402 &rate_idx); 2380 &rate_idx);
2403 2381
2404 /* Indicate to uCode which entries might be MIMO. 2382 /* Indicate to uCode which entries might be MIMO.
@@ -2408,8 +2386,8 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
2408 lq_cmd->general_params.mimo_delimiter = index; 2386 lq_cmd->general_params.mimo_delimiter = index;
2409 2387
2410 /* Get next rate */ 2388 /* Get next rate */
2411 rs_get_lower_rate(lq_sta, &tbl_type, rate_idx, 2389 new_rate = rs_get_lower_rate(lq_sta, &tbl_type, rate_idx,
2412 use_ht_possible, &new_rate); 2390 use_ht_possible);
2413 2391
2414 /* How many times should we repeat the next rate? */ 2392 /* How many times should we repeat the next rate? */
2415 if (is_legacy(tbl_type.lq_type)) { 2393 if (is_legacy(tbl_type.lq_type)) {
@@ -2433,8 +2411,7 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv,
2433 rs_dbgfs_set_mcs(lq_sta, &new_rate, index); 2411 rs_dbgfs_set_mcs(lq_sta, &new_rate, index);
2434 2412
2435 /* Fill next table entry */ 2413 /* Fill next table entry */
2436 lq_cmd->rs_table[index].rate_n_flags = 2414 lq_cmd->rs_table[index].rate_n_flags = cpu_to_le32(new_rate);
2437 cpu_to_le32(new_rate.rate_n_flags);
2438 2415
2439 index++; 2416 index++;
2440 repeat_rate--; 2417 repeat_rate--;
@@ -2483,25 +2460,21 @@ static int open_file_generic(struct inode *inode, struct file *file)
2483 return 0; 2460 return 0;
2484} 2461}
2485static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, 2462static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
2486 struct iwl4965_rate *mcs, int index) 2463 u32 *rate_n_flags, int index)
2487{ 2464{
2488 u32 base_rate; 2465 if (lq_sta->dbg_fixed_rate) {
2489 2466 if (index < 12) {
2490 if (lq_sta->band == IEEE80211_BAND_5GHZ) 2467 *rate_n_flags = lq_sta->dbg_fixed_rate;
2491 base_rate = 0x800D; 2468 } else {
2492 else 2469 if (lq_sta->band == IEEE80211_BAND_5GHZ)
2493 base_rate = 0x820A; 2470 *rate_n_flags = 0x800D;
2494 2471 else
2495 if (lq_sta->dbg_fixed.rate_n_flags) { 2472 *rate_n_flags = 0x820A;
2496 if (index < 12) 2473 }
2497 mcs->rate_n_flags = lq_sta->dbg_fixed.rate_n_flags;
2498 else
2499 mcs->rate_n_flags = base_rate;
2500 IWL_DEBUG_RATE("Fixed rate ON\n"); 2474 IWL_DEBUG_RATE("Fixed rate ON\n");
2501 return; 2475 } else {
2476 IWL_DEBUG_RATE("Fixed rate OFF\n");
2502 } 2477 }
2503
2504 IWL_DEBUG_RATE("Fixed rate OFF\n");
2505} 2478}
2506 2479
2507static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, 2480static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
@@ -2518,20 +2491,21 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2518 return -EFAULT; 2491 return -EFAULT;
2519 2492
2520 if (sscanf(buf, "%x", &parsed_rate) == 1) 2493 if (sscanf(buf, "%x", &parsed_rate) == 1)
2521 lq_sta->dbg_fixed.rate_n_flags = parsed_rate; 2494 lq_sta->dbg_fixed_rate = parsed_rate;
2522 else 2495 else
2523 lq_sta->dbg_fixed.rate_n_flags = 0; 2496 lq_sta->dbg_fixed_rate = 0;
2524 2497
2525 lq_sta->active_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ 2498 lq_sta->active_legacy_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
2526 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ 2499 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2527 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ 2500 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2528 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ 2501 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2529 2502
2530 IWL_DEBUG_RATE("sta_id %d rate 0x%X\n", 2503 IWL_DEBUG_RATE("sta_id %d rate 0x%X\n",
2531 lq_sta->lq.sta_id, lq_sta->dbg_fixed.rate_n_flags); 2504 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
2532 2505
2533 if (lq_sta->dbg_fixed.rate_n_flags) { 2506 if (lq_sta->dbg_fixed_rate) {
2534 rs_fill_link_cmd(NULL, lq_sta, &lq_sta->dbg_fixed, &lq_sta->lq); 2507 rs_fill_link_cmd(NULL, lq_sta, lq_sta->dbg_fixed_rate,
2508 &lq_sta->lq);
2535 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC); 2509 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC);
2536 } 2510 }
2537 2511
@@ -2550,9 +2524,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
2550 desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id); 2524 desc += sprintf(buff+desc, "sta_id %d\n", lq_sta->lq.sta_id);
2551 desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n", 2525 desc += sprintf(buff+desc, "failed=%d success=%d rate=0%X\n",
2552 lq_sta->total_failed, lq_sta->total_success, 2526 lq_sta->total_failed, lq_sta->total_success,
2553 lq_sta->active_rate); 2527 lq_sta->active_legacy_rate);
2554 desc += sprintf(buff+desc, "fixed rate 0x%X\n", 2528 desc += sprintf(buff+desc, "fixed rate 0x%X\n",
2555 lq_sta->dbg_fixed.rate_n_flags); 2529 lq_sta->dbg_fixed_rate);
2556 desc += sprintf(buff+desc, "general:" 2530 desc += sprintf(buff+desc, "general:"
2557 "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n", 2531 "flags=0x%X mimo-d=%d s-ant0x%x d-ant=0x%x\n",
2558 lq_sta->lq.general_params.flags, 2532 lq_sta->lq.general_params.flags,
@@ -2602,7 +2576,7 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
2602 lq_sta->lq_info[i].is_SGI, 2576 lq_sta->lq_info[i].is_SGI,
2603 lq_sta->lq_info[i].is_fat, 2577 lq_sta->lq_info[i].is_fat,
2604 lq_sta->lq_info[i].is_dup, 2578 lq_sta->lq_info[i].is_dup,
2605 lq_sta->lq_info[i].current_rate.rate_n_flags); 2579 lq_sta->lq_info[i].current_rate);
2606 for (j = 0; j < IWL_RATE_COUNT; j++) { 2580 for (j = 0; j < IWL_RATE_COUNT; j++) {
2607 desc += sprintf(buff+desc, 2581 desc += sprintf(buff+desc,
2608 "counter=%d success=%d %%=%d\n", 2582 "counter=%d success=%d %%=%d\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 783f722f3c35..3452cc662429 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -1073,17 +1073,29 @@ unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv,
1073 return priv->ibss_beacon->len; 1073 return priv->ibss_beacon->len;
1074} 1074}
1075 1075
1076static u8 iwl4965_rate_get_lowest_plcp(int rate_mask) 1076static u8 iwl4965_rate_get_lowest_plcp(struct iwl_priv *priv)
1077{ 1077{
1078 u8 i; 1078 int i;
1079 int rate_mask;
1080
1081 /* Set rate mask*/
1082 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
1083 rate_mask = priv->active_rate_basic & 0xF;
1084 else
1085 rate_mask = priv->active_rate_basic & 0xFF0;
1079 1086
1087 /* Find lowest valid rate */
1080 for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID; 1088 for (i = IWL_RATE_1M_INDEX; i != IWL_RATE_INVALID;
1081 i = iwl4965_rates[i].next_ieee) { 1089 i = iwl4965_rates[i].next_ieee) {
1082 if (rate_mask & (1 << i)) 1090 if (rate_mask & (1 << i))
1083 return iwl4965_rates[i].plcp; 1091 return iwl4965_rates[i].plcp;
1084 } 1092 }
1085 1093
1086 return IWL_RATE_INVALID; 1094 /* No valid rate was found. Assign the lowest one */
1095 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)
1096 return IWL_RATE_1M_PLCP;
1097 else
1098 return IWL_RATE_6M_PLCP;
1087} 1099}
1088 1100
1089static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) 1101static int iwl4965_send_beacon_cmd(struct iwl_priv *priv)
@@ -1101,16 +1113,7 @@ static int iwl4965_send_beacon_cmd(struct iwl_priv *priv)
1101 return -ENOMEM; 1113 return -ENOMEM;
1102 } 1114 }
1103 1115
1104 if (!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK)) { 1116 rate = iwl4965_rate_get_lowest_plcp(priv);
1105 rate = iwl4965_rate_get_lowest_plcp(priv->active_rate_basic &
1106 0xFF0);
1107 if (rate == IWL_INVALID_RATE)
1108 rate = IWL_RATE_6M_PLCP;
1109 } else {
1110 rate = iwl4965_rate_get_lowest_plcp(priv->active_rate_basic & 0xF);
1111 if (rate == IWL_INVALID_RATE)
1112 rate = IWL_RATE_1M_PLCP;
1113 }
1114 1117
1115 frame_size = iwl4965_hw_get_beacon_cmd(priv, frame, rate); 1118 frame_size = iwl4965_hw_get_beacon_cmd(priv, frame, rate);
1116 1119