diff options
author | Guy Cohen <guy.cohen@intel.com> | 2008-04-23 20:14:57 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-07 15:02:18 -0400 |
commit | 39e885049d9d5e6a65bb2543f82e136c02c253b5 (patch) | |
tree | 86edc7552e5b0ad423845f0ec91b6cd809460e67 | |
parent | 399f490067992715044cbf2be1923e2f613b2e18 (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.c | 434 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 31 |
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 | ||
67 | struct 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); |
174 | static void rs_fill_link_cmd(const struct iwl_priv *priv, | 170 | static 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 |
181 | static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, | 177 | static 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 |
184 | static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, | 180 | static 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 | ||
235 | static inline u8 iwl4965_rate_get_rate(u32 rate_n_flags) | 231 | static 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 | ||
379 | static inline int get_num_of_ant_from_mcs(u32 mcs) | 375 | static 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 | */ |
470 | static 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, | 465 | static 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 | */ |
525 | static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate, | 520 | static 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 */ |
585 | static inline void rs_toggle_antenna(struct iwl4965_rate *new_rate, | 580 | static 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 */ | ||
592 | static inline u8 rs_use_green(struct iwl_priv *priv, | 588 | static 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 | ||
687 | static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta, | 684 | static 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); | 736 | out: |
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 | ||
2060 | out: | 2042 | out: |
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 | ||
2327 | static void rs_fill_link_cmd(const struct iwl_priv *priv, | 2308 | static 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 | } |
2485 | static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta, | 2462 | static 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 | ||
2507 | static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file, | 2480 | static 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 | ||
1076 | static u8 iwl4965_rate_get_lowest_plcp(int rate_mask) | 1076 | static 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 | ||
1089 | static int iwl4965_send_beacon_cmd(struct iwl_priv *priv) | 1101 | static 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 | ||