aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorGuy Cohen <guy.cohen@intel.com>2008-04-21 18:42:01 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-07 15:02:16 -0400
commitfde0db310fd4979e0d8e6ba009975d23cc7e65ac (patch)
tree79bc5dab39cce0cbc2b4d40433b53c048efbd38a /drivers/net
parentd1141dfb3ab5545491e3aa15b7f0d7330a186281 (diff)
iwlwifi: HT antenna/chains overhaul
1. This patch restructures rate scale algorithm to support SISO, MIMO2, MIMO3 2. It adds support for detailed valid TX and RX antennas settings 3. It removes few unesfull antenna definitions 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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-commands.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.c337
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965-rs.h85
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c57
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.h15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl4965-base.c39
7 files changed, 262 insertions, 283 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h
index b2fa58d2d174..7ffae05a930e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-commands.h
@@ -269,10 +269,11 @@ struct iwl_cmd_header {
269 * 10 B active, A inactive 269 * 10 B active, A inactive
270 * 11 Both active 270 * 11 Both active
271 */ 271 */
272#define RATE_MCS_ANT_POS 14 272#define RATE_MCS_ANT_POS 14
273#define RATE_MCS_ANT_A_MSK 0x04000 273#define RATE_MCS_ANT_A_MSK 0x04000
274#define RATE_MCS_ANT_B_MSK 0x08000 274#define RATE_MCS_ANT_B_MSK 0x08000
275#define RATE_MCS_ANT_AB_MSK 0x0C000 275#define RATE_MCS_ANT_C_MSK 0x10000
276#define RATE_MCS_ANT_ABC_MSK 0x1C000
276 277
277 278
278/** 279/**
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
index e20c9385c358..31a0451f7a4d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.c
@@ -87,8 +87,8 @@ struct iwl4965_rate_scale_data {
87 * one for "active", and one for "search". 87 * one for "active", and one for "search".
88 */ 88 */
89struct iwl4965_scale_tbl_info { 89struct iwl4965_scale_tbl_info {
90 enum iwl4965_table_type lq_type; 90 enum iwl_table_type lq_type;
91 enum iwl4965_antenna_type antenna_type; 91 u8 ant_type;
92 u8 is_SGI; /* 1 = short guard interval */ 92 u8 is_SGI; /* 1 = short guard interval */
93 u8 is_fat; /* 1 = 40 MHz channel width */ 93 u8 is_fat; /* 1 = 40 MHz channel width */
94 u8 is_dup; /* 1 = duplicated data streams */ 94 u8 is_dup; /* 1 = duplicated data streams */
@@ -146,7 +146,8 @@ struct iwl4965_lq_sta {
146 u32 supp_rates; 146 u32 supp_rates;
147 u16 active_rate; 147 u16 active_rate;
148 u16 active_siso_rate; 148 u16 active_siso_rate;
149 u16 active_mimo_rate; 149 u16 active_mimo2_rate;
150 u16 active_mimo3_rate;
150 u16 active_rate_basic; 151 u16 active_rate_basic;
151 152
152 struct iwl_link_quality_cmd lq; 153 struct iwl_link_quality_cmd lq;
@@ -170,7 +171,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
170 struct net_device *dev, 171 struct net_device *dev,
171 struct ieee80211_hdr *hdr, 172 struct ieee80211_hdr *hdr,
172 struct sta_info *sta); 173 struct sta_info *sta);
173static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, 174static void rs_fill_link_cmd(const struct iwl_priv *priv,
175 struct iwl4965_lq_sta *lq_sta,
174 struct iwl4965_rate *tx_mcs, 176 struct iwl4965_rate *tx_mcs,
175 struct iwl_link_quality_cmd *tbl); 177 struct iwl_link_quality_cmd *tbl);
176 178
@@ -189,6 +191,7 @@ static void rs_dbgfs_set_mcs(struct iwl4965_lq_sta *lq_sta,
189 * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits 191 * 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 60 MBits
190 * "G" is the only table that supports CCK (the first 4 rates). 192 * "G" is the only table that supports CCK (the first 4 rates).
191 */ 193 */
194/*FIXME:RS:need to spearate tables for MIMO2/MIMO3*/
192static s32 expected_tpt_A[IWL_RATE_COUNT] = { 195static s32 expected_tpt_A[IWL_RATE_COUNT] = {
193 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186 196 0, 0, 0, 0, 40, 57, 72, 98, 121, 154, 177, 186, 186
194}; 197};
@@ -373,6 +376,13 @@ static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid,
373 376
374#endif /* CONFIG_IWLWIFI_HT */ 377#endif /* CONFIG_IWLWIFI_HT */
375 378
379static inline int get_num_of_ant_from_mcs(u32 mcs)
380{
381 return (!!(mcs & RATE_MCS_ANT_A_MSK) +
382 !!(mcs & RATE_MCS_ANT_B_MSK) +
383 !!(mcs & RATE_MCS_ANT_C_MSK));
384}
385
376/** 386/**
377 * rs_collect_tx_data - Update the success/failure sliding window 387 * rs_collect_tx_data - Update the success/failure sliding window
378 * 388 *
@@ -466,31 +476,28 @@ static void rs_mcs_from_tbl(struct iwl4965_rate *mcs_rate,
466 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE) 476 if (index >= IWL_FIRST_CCK_RATE && index <= IWL_LAST_CCK_RATE)
467 mcs_rate->rate_n_flags |= RATE_MCS_CCK_MSK; 477 mcs_rate->rate_n_flags |= RATE_MCS_CCK_MSK;
468 478
469 } else if (is_siso(tbl->lq_type)) { 479 } else if (is_Ht(tbl->lq_type)) {
470 if (index > IWL_LAST_OFDM_RATE) 480 if (index > IWL_LAST_OFDM_RATE) {
481 IWL_ERROR("invalid HT rate index %d\n", index);
471 index = IWL_LAST_OFDM_RATE; 482 index = IWL_LAST_OFDM_RATE;
472 mcs_rate->rate_n_flags = iwl4965_rates[index].plcp_siso | 483 }
473 RATE_MCS_HT_MSK; 484 mcs_rate->rate_n_flags = RATE_MCS_HT_MSK;
485
486 if (is_siso(tbl->lq_type))
487 mcs_rate->rate_n_flags |=
488 iwl4965_rates[index].plcp_siso;
489 else if (is_mimo2(tbl->lq_type))
490 mcs_rate->rate_n_flags |=
491 iwl4965_rates[index].plcp_mimo2;
492 else
493 mcs_rate->rate_n_flags |=
494 iwl4965_rates[index].plcp_mimo3;
474 } else { 495 } else {
475 if (index > IWL_LAST_OFDM_RATE) 496 IWL_ERROR("Invalid tbl->lq_type %d\n", tbl->lq_type);
476 index = IWL_LAST_OFDM_RATE;
477 mcs_rate->rate_n_flags = iwl4965_rates[index].plcp_mimo |
478 RATE_MCS_HT_MSK;
479 } 497 }
480 498
481 switch (tbl->antenna_type) { 499 mcs_rate->rate_n_flags |= ((tbl->ant_type << RATE_MCS_ANT_POS) &
482 case ANT_BOTH: 500 RATE_MCS_ANT_ABC_MSK);
483 mcs_rate->rate_n_flags |= RATE_MCS_ANT_AB_MSK;
484 break;
485 case ANT_MAIN:
486 mcs_rate->rate_n_flags |= RATE_MCS_ANT_A_MSK;
487 break;
488 case ANT_AUX:
489 mcs_rate->rate_n_flags |= RATE_MCS_ANT_B_MSK;
490 break;
491 case ANT_NONE:
492 break;
493 }
494 501
495 if (is_legacy(tbl->lq_type)) 502 if (is_legacy(tbl->lq_type))
496 return; 503 return;
@@ -520,69 +527,31 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
520 struct iwl4965_scale_tbl_info *tbl, 527 struct iwl4965_scale_tbl_info *tbl,
521 int *rate_idx) 528 int *rate_idx)
522{ 529{
523 int index; 530 u32 ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_ABC_MSK);
524 u32 ant_msk; 531 u8 num_of_ant = get_num_of_ant_from_mcs(ant_msk);
525 532
526 index = iwl4965_hwrate_to_plcp_idx(mcs_rate->rate_n_flags); 533 *rate_idx = iwl4965_hwrate_to_plcp_idx(mcs_rate->rate_n_flags);
527 534
528 if (index == IWL_RATE_INVALID) { 535 if (*rate_idx == IWL_RATE_INVALID) {
529 *rate_idx = -1; 536 *rate_idx = -1;
530 return -EINVAL; 537 return -EINVAL;
531 } 538 }
532 tbl->is_SGI = 0; /* default legacy setup */ 539 tbl->is_SGI = 0; /* default legacy setup */
533 tbl->is_fat = 0; 540 tbl->is_fat = 0;
534 tbl->is_dup = 0; 541 tbl->is_dup = 0;
535 tbl->antenna_type = ANT_BOTH; /* default MIMO setup */ 542 tbl->ant_type = (ant_msk >> RATE_MCS_ANT_POS);
543 tbl->lq_type = LQ_NONE;
536 544
537 /* legacy rate format */ 545 /* legacy rate format */
538 if (!(mcs_rate->rate_n_flags & RATE_MCS_HT_MSK)) { 546 if (!(mcs_rate->rate_n_flags & RATE_MCS_HT_MSK)) {
539 ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_AB_MSK); 547 if (num_of_ant == 1) {
540
541 if (ant_msk == RATE_MCS_ANT_AB_MSK)
542 tbl->lq_type = LQ_NONE;
543 else {
544
545 if (band == IEEE80211_BAND_5GHZ) 548 if (band == IEEE80211_BAND_5GHZ)
546 tbl->lq_type = LQ_A; 549 tbl->lq_type = LQ_A;
547 else 550 else
548 tbl->lq_type = LQ_G; 551 tbl->lq_type = LQ_G;
549
550 if (mcs_rate->rate_n_flags & RATE_MCS_ANT_A_MSK)
551 tbl->antenna_type = ANT_MAIN;
552 else
553 tbl->antenna_type = ANT_AUX;
554 }
555 *rate_idx = index;
556
557 /* HT rate format, SISO (might be 20 MHz legacy or 40 MHz fat width) */
558 } else if (iwl4965_rate_get_rate(mcs_rate->rate_n_flags)
559 <= IWL_RATE_SISO_60M_PLCP) {
560 tbl->lq_type = LQ_SISO;
561
562 ant_msk = (mcs_rate->rate_n_flags & RATE_MCS_ANT_AB_MSK);
563 if (ant_msk == RATE_MCS_ANT_AB_MSK)
564 tbl->lq_type = LQ_NONE;
565 else {
566 if (mcs_rate->rate_n_flags & RATE_MCS_ANT_A_MSK)
567 tbl->antenna_type = ANT_MAIN;
568 else
569 tbl->antenna_type = ANT_AUX;
570 } 552 }
571 if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK) 553 /* HT rate format */
572 tbl->is_SGI = 1;
573
574 if ((mcs_rate->rate_n_flags & RATE_MCS_FAT_MSK) ||
575 (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK))
576 tbl->is_fat = 1;
577
578 if (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK)
579 tbl->is_dup = 1;
580
581 *rate_idx = index;
582
583 /* HT rate format, MIMO (might be 20 MHz legacy or 40 MHz fat width) */
584 } else { 554 } else {
585 tbl->lq_type = LQ_MIMO;
586 if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK) 555 if (mcs_rate->rate_n_flags & RATE_MCS_SGI_MSK)
587 tbl->is_SGI = 1; 556 tbl->is_SGI = 1;
588 557
@@ -592,23 +561,32 @@ static int rs_get_tbl_info_from_mcs(const struct iwl4965_rate *mcs_rate,
592 561
593 if (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK) 562 if (mcs_rate->rate_n_flags & RATE_MCS_DUP_MSK)
594 tbl->is_dup = 1; 563 tbl->is_dup = 1;
595 *rate_idx = index; 564
565 /* SISO */
566 if (iwl4965_rate_get_rate(mcs_rate->rate_n_flags)
567 <= IWL_RATE_SISO_60M_PLCP) {
568
569 if (num_of_ant == 1)
570 tbl->lq_type = LQ_SISO; /*else NONE*/
571 /* MIMO2 */
572 } else if (iwl4965_rate_get_rate(mcs_rate->rate_n_flags)
573 <= IWL_RATE_MIMO2_60M_PLCP) {
574 if (num_of_ant == 2)
575 tbl->lq_type = LQ_MIMO2;
576 /* MIMO3 */
577 } else {
578 if (num_of_ant == 3)
579 tbl->lq_type = LQ_MIMO3;
580 }
596 } 581 }
597 return 0; 582 return 0;
598} 583}
599 584/* FIXME:RS: need to toggle also ANT_C, and also AB,AC,BC */
600static inline void rs_toggle_antenna(struct iwl4965_rate *new_rate, 585static inline void rs_toggle_antenna(struct iwl4965_rate *new_rate,
601 struct iwl4965_scale_tbl_info *tbl) 586 struct iwl4965_scale_tbl_info *tbl)
602{ 587{
603 if (tbl->antenna_type == ANT_AUX) { 588 tbl->ant_type ^= ANT_AB;
604 tbl->antenna_type = ANT_MAIN; 589 new_rate->rate_n_flags ^= (RATE_MCS_ANT_A_MSK|RATE_MCS_ANT_B_MSK);
605 new_rate->rate_n_flags &= ~RATE_MCS_ANT_B_MSK;
606 new_rate->rate_n_flags |= RATE_MCS_ANT_A_MSK;
607 } else {
608 tbl->antenna_type = ANT_AUX;
609 new_rate->rate_n_flags &= ~RATE_MCS_ANT_A_MSK;
610 new_rate->rate_n_flags |= RATE_MCS_ANT_B_MSK;
611 }
612} 590}
613 591
614static inline u8 rs_use_green(struct iwl_priv *priv, 592static inline u8 rs_use_green(struct iwl_priv *priv,
@@ -631,7 +609,7 @@ static inline u8 rs_use_green(struct iwl_priv *priv,
631 */ 609 */
632static void rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta, 610static void rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta,
633 struct ieee80211_hdr *hdr, 611 struct ieee80211_hdr *hdr,
634 enum iwl4965_table_type rate_type, 612 enum iwl_table_type rate_type,
635 u16 *data_rate) 613 u16 *data_rate)
636{ 614{
637 if (is_legacy(rate_type)) 615 if (is_legacy(rate_type))
@@ -639,8 +617,10 @@ static void rs_get_supported_rates(struct iwl4965_lq_sta *lq_sta,
639 else { 617 else {
640 if (is_siso(rate_type)) 618 if (is_siso(rate_type))
641 *data_rate = lq_sta->active_siso_rate; 619 *data_rate = lq_sta->active_siso_rate;
620 else if (is_mimo2(rate_type))
621 *data_rate = lq_sta->active_mimo2_rate;
642 else 622 else
643 *data_rate = lq_sta->active_mimo_rate; 623 *data_rate = lq_sta->active_mimo3_rate;
644 } 624 }
645 625
646 if (hdr && is_multicast_ether_addr(hdr->addr1) && 626 if (hdr && is_multicast_ether_addr(hdr->addr1) &&
@@ -725,9 +705,8 @@ static void rs_get_lower_rate(struct iwl4965_lq_sta *lq_sta,
725 else 705 else
726 tbl->lq_type = LQ_G; 706 tbl->lq_type = LQ_G;
727 707
728 if ((tbl->antenna_type == ANT_BOTH) || 708 if (num_of_ant(tbl->ant_type > 1))
729 (tbl->antenna_type == ANT_NONE)) 709 tbl->ant_type = ANT_A;/*FIXME:RS*/
730 tbl->antenna_type = ANT_MAIN;
731 710
732 tbl->is_fat = 0; 711 tbl->is_fat = 0;
733 tbl->is_SGI = 0; 712 tbl->is_SGI = 0;
@@ -821,13 +800,6 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
821 table = &lq_sta->lq; 800 table = &lq_sta->lq;
822 active_index = lq_sta->active_tbl; 801 active_index = lq_sta->active_tbl;
823 802
824 /* Get mac80211 antenna info */
825 lq_sta->antenna =
826 (lq_sta->valid_antenna & local->hw.conf.antenna_sel_tx);
827 if (!lq_sta->antenna)
828 lq_sta->antenna = lq_sta->valid_antenna;
829
830 /* Ignore mac80211 antenna info for now */
831 lq_sta->antenna = lq_sta->valid_antenna; 803 lq_sta->antenna = lq_sta->valid_antenna;
832 804
833 curr_tbl = &(lq_sta->lq_info[active_index]); 805 curr_tbl = &(lq_sta->lq_info[active_index]);
@@ -857,8 +829,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
857 !!(tx_resp->control.flags & IEEE80211_TXCTL_40_MHZ_WIDTH)) || 829 !!(tx_resp->control.flags & IEEE80211_TXCTL_40_MHZ_WIDTH)) ||
858 (tbl_type.is_dup ^ 830 (tbl_type.is_dup ^
859 !!(tx_resp->control.flags & IEEE80211_TXCTL_DUP_DATA)) || 831 !!(tx_resp->control.flags & IEEE80211_TXCTL_DUP_DATA)) ||
860 (tbl_type.antenna_type ^ 832 (tbl_type.ant_type ^ tx_resp->control.antenna_sel_tx) ||
861 tx_resp->control.antenna_sel_tx) ||
862 (!!(tx_mcs.rate_n_flags & RATE_MCS_HT_MSK) ^ 833 (!!(tx_mcs.rate_n_flags & RATE_MCS_HT_MSK) ^
863 !!(tx_resp->control.flags & IEEE80211_TXCTL_OFDM_HT)) || 834 !!(tx_resp->control.flags & IEEE80211_TXCTL_OFDM_HT)) ||
864 (!!(tx_mcs.rate_n_flags & RATE_MCS_GF_MSK) ^ 835 (!!(tx_mcs.rate_n_flags & RATE_MCS_GF_MSK) ^
@@ -882,7 +853,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
882 /* If type matches "search" table, 853 /* If type matches "search" table,
883 * add failure to "search" history */ 854 * add failure to "search" history */
884 if ((tbl_type.lq_type == search_tbl->lq_type) && 855 if ((tbl_type.lq_type == search_tbl->lq_type) &&
885 (tbl_type.antenna_type == search_tbl->antenna_type) && 856 (tbl_type.ant_type == search_tbl->ant_type) &&
886 (tbl_type.is_SGI == search_tbl->is_SGI)) { 857 (tbl_type.is_SGI == search_tbl->is_SGI)) {
887 if (search_tbl->expected_tpt) 858 if (search_tbl->expected_tpt)
888 tpt = search_tbl->expected_tpt[rs_index]; 859 tpt = search_tbl->expected_tpt[rs_index];
@@ -893,7 +864,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
893 /* Else if type matches "current/active" table, 864 /* Else if type matches "current/active" table,
894 * add failure to "current/active" history */ 865 * add failure to "current/active" history */
895 } else if ((tbl_type.lq_type == curr_tbl->lq_type) && 866 } else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
896 (tbl_type.antenna_type == curr_tbl->antenna_type) && 867 (tbl_type.ant_type == curr_tbl->ant_type) &&
897 (tbl_type.is_SGI == curr_tbl->is_SGI)) { 868 (tbl_type.is_SGI == curr_tbl->is_SGI)) {
898 if (curr_tbl->expected_tpt) 869 if (curr_tbl->expected_tpt)
899 tpt = curr_tbl->expected_tpt[rs_index]; 870 tpt = curr_tbl->expected_tpt[rs_index];
@@ -928,7 +899,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
928 /* If type matches "search" table, 899 /* If type matches "search" table,
929 * add final tx status to "search" history */ 900 * add final tx status to "search" history */
930 if ((tbl_type.lq_type == search_tbl->lq_type) && 901 if ((tbl_type.lq_type == search_tbl->lq_type) &&
931 (tbl_type.antenna_type == search_tbl->antenna_type) && 902 (tbl_type.ant_type == search_tbl->ant_type) &&
932 (tbl_type.is_SGI == search_tbl->is_SGI)) { 903 (tbl_type.is_SGI == search_tbl->is_SGI)) {
933 if (search_tbl->expected_tpt) 904 if (search_tbl->expected_tpt)
934 tpt = search_tbl->expected_tpt[rs_index]; 905 tpt = search_tbl->expected_tpt[rs_index];
@@ -944,7 +915,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev,
944 /* Else if type matches "current/active" table, 915 /* Else if type matches "current/active" table,
945 * add final tx status to "current/active" history */ 916 * add final tx status to "current/active" history */
946 } else if ((tbl_type.lq_type == curr_tbl->lq_type) && 917 } else if ((tbl_type.lq_type == curr_tbl->lq_type) &&
947 (tbl_type.antenna_type == curr_tbl->antenna_type) && 918 (tbl_type.ant_type == curr_tbl->ant_type) &&
948 (tbl_type.is_SGI == curr_tbl->is_SGI)) { 919 (tbl_type.is_SGI == curr_tbl->is_SGI)) {
949 if (curr_tbl->expected_tpt) 920 if (curr_tbl->expected_tpt)
950 tpt = curr_tbl->expected_tpt[rs_index]; 921 tpt = curr_tbl->expected_tpt[rs_index];
@@ -981,26 +952,18 @@ out:
981 return; 952 return;
982} 953}
983 954
984static u8 rs_is_ant_connected(u8 valid_antenna, 955static inline u8 rs_is_ant_connected(u8 valid_antenna, u8 ant_type)
985 enum iwl4965_antenna_type antenna_type)
986{ 956{
987 if (antenna_type == ANT_AUX) 957 return ((ant_type & valid_antenna) == ant_type);
988 return ((valid_antenna & 0x2) ? 1:0);
989 else if (antenna_type == ANT_MAIN)
990 return ((valid_antenna & 0x1) ? 1:0);
991 else if (antenna_type == ANT_BOTH)
992 return ((valid_antenna & 0x3) == 0x3);
993
994 return 1;
995} 958}
996 959
997static u8 rs_is_other_ant_connected(u8 valid_antenna, 960/*FIXME:RS: this function should be replaced*/
998 enum iwl4965_antenna_type antenna_type) 961static u8 rs_is_other_ant_connected(u8 valid_antenna, u8 ant_type)
999{ 962{
1000 if (antenna_type == ANT_AUX) 963 if (ant_type == ANT_B)
1001 return rs_is_ant_connected(valid_antenna, ANT_MAIN); 964 return rs_is_ant_connected(valid_antenna, ANT_A);
1002 else 965 else
1003 return rs_is_ant_connected(valid_antenna, ANT_AUX); 966 return rs_is_ant_connected(valid_antenna, ANT_B);
1004 967
1005 return 0; 968 return 0;
1006} 969}
@@ -1054,7 +1017,7 @@ static void rs_get_expected_tpt_table(struct iwl4965_lq_sta *lq_sta,
1054 else 1017 else
1055 tbl->expected_tpt = expected_tpt_siso20MHz; 1018 tbl->expected_tpt = expected_tpt_siso20MHz;
1056 1019
1057 } else if (is_mimo(tbl->lq_type)) { 1020 } else if (is_mimo(tbl->lq_type)) { /* FIXME:need to separate mimo2/3 */
1058 if (tbl->is_fat && !lq_sta->is_dup) 1021 if (tbl->is_fat && !lq_sta->is_dup)
1059 if (tbl->is_SGI) 1022 if (tbl->is_SGI)
1060 tbl->expected_tpt = expected_tpt_mimo40MHzSGI; 1023 tbl->expected_tpt = expected_tpt_mimo40MHzSGI;
@@ -1171,21 +1134,22 @@ static s32 rs_get_best_rate(struct iwl_priv *priv,
1171} 1134}
1172#endif /* CONFIG_IWL4965_HT */ 1135#endif /* CONFIG_IWL4965_HT */
1173 1136
1137/*FIXME:RS:this function should be replaced*/
1174static inline u8 rs_is_both_ant_supp(u8 valid_antenna) 1138static inline u8 rs_is_both_ant_supp(u8 valid_antenna)
1175{ 1139{
1176 return (rs_is_ant_connected(valid_antenna, ANT_BOTH)); 1140 return (rs_is_ant_connected(valid_antenna, ANT_AB));
1177} 1141}
1178 1142
1179/* 1143/*
1180 * Set up search table for MIMO 1144 * Set up search table for MIMO
1181 */ 1145 */
1182static int rs_switch_to_mimo(struct iwl_priv *priv, 1146#ifdef CONFIG_IWL4965_HT
1147static int rs_switch_to_mimo2(struct iwl_priv *priv,
1183 struct iwl4965_lq_sta *lq_sta, 1148 struct iwl4965_lq_sta *lq_sta,
1184 struct ieee80211_conf *conf, 1149 struct ieee80211_conf *conf,
1185 struct sta_info *sta, 1150 struct sta_info *sta,
1186 struct iwl4965_scale_tbl_info *tbl, int index) 1151 struct iwl4965_scale_tbl_info *tbl, int index)
1187{ 1152{
1188#ifdef CONFIG_IWL4965_HT
1189 u16 rate_mask; 1153 u16 rate_mask;
1190 s32 rate; 1154 s32 rate;
1191 s8 is_green = lq_sta->is_green; 1155 s8 is_green = lq_sta->is_green;
@@ -1195,7 +1159,7 @@ static int rs_switch_to_mimo(struct iwl_priv *priv,
1195 return -1; 1159 return -1;
1196 1160
1197 IWL_DEBUG_HT("LQ: try to switch to MIMO\n"); 1161 IWL_DEBUG_HT("LQ: try to switch to MIMO\n");
1198 tbl->lq_type = LQ_MIMO; 1162 tbl->lq_type = LQ_MIMO2;
1199 rs_get_supported_rates(lq_sta, NULL, tbl->lq_type, 1163 rs_get_supported_rates(lq_sta, NULL, tbl->lq_type,
1200 &rate_mask); 1164 &rate_mask);
1201 1165
@@ -1203,7 +1167,7 @@ static int rs_switch_to_mimo(struct iwl_priv *priv,
1203 return -1; 1167 return -1;
1204 1168
1205 /* Need both Tx chains/antennas to support MIMO */ 1169 /* Need both Tx chains/antennas to support MIMO */
1206 if (!rs_is_both_ant_supp(lq_sta->antenna)) 1170 if (!rs_is_both_ant_supp(priv->hw_params.valid_tx_ant))
1207 return -1; 1171 return -1;
1208 1172
1209 tbl->is_dup = lq_sta->is_dup; 1173 tbl->is_dup = lq_sta->is_dup;
@@ -1236,10 +1200,17 @@ static int rs_switch_to_mimo(struct iwl_priv *priv,
1236 IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n", 1200 IWL_DEBUG_HT("LQ: Switch to new mcs %X index is green %X\n",
1237 tbl->current_rate.rate_n_flags, is_green); 1201 tbl->current_rate.rate_n_flags, is_green);
1238 return 0; 1202 return 0;
1203}
1239#else 1204#else
1205static int rs_switch_to_mimo2(struct iwl_priv *priv,
1206 struct iwl4965_lq_sta *lq_sta,
1207 struct ieee80211_conf *conf,
1208 struct sta_info *sta,
1209 struct iwl4965_scale_tbl_info *tbl, int index)
1210{
1240 return -1; 1211 return -1;
1241#endif /*CONFIG_IWL4965_HT */
1242} 1212}
1213#endif /*CONFIG_IWL4965_HT */
1243 1214
1244/* 1215/*
1245 * Set up search table for SISO 1216 * Set up search table for SISO
@@ -1313,7 +1284,6 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1313 struct sta_info *sta, 1284 struct sta_info *sta,
1314 int index) 1285 int index)
1315{ 1286{
1316 int ret = 0;
1317 struct iwl4965_scale_tbl_info *tbl = 1287 struct iwl4965_scale_tbl_info *tbl =
1318 &(lq_sta->lq_info[lq_sta->active_tbl]); 1288 &(lq_sta->lq_info[lq_sta->active_tbl]);
1319 struct iwl4965_scale_tbl_info *search_tbl = 1289 struct iwl4965_scale_tbl_info *search_tbl =
@@ -1322,6 +1292,8 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1322 u32 sz = (sizeof(struct iwl4965_scale_tbl_info) - 1292 u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
1323 (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT)); 1293 (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
1324 u8 start_action = tbl->action; 1294 u8 start_action = tbl->action;
1295 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1296 int ret = 0;
1325 1297
1326 for (; ;) { 1298 for (; ;) {
1327 switch (tbl->action) { 1299 switch (tbl->action) {
@@ -1336,8 +1308,8 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1336 break; 1308 break;
1337 1309
1338 /* Don't change antenna if other one is not connected */ 1310 /* Don't change antenna if other one is not connected */
1339 if (!rs_is_other_ant_connected(lq_sta->antenna, 1311 if (!rs_is_other_ant_connected(valid_tx_ant,
1340 tbl->antenna_type)) 1312 tbl->ant_type))
1341 break; 1313 break;
1342 1314
1343 /* Set up search table to try other antenna */ 1315 /* Set up search table to try other antenna */
@@ -1366,16 +1338,17 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1366 } 1338 }
1367 1339
1368 break; 1340 break;
1369 case IWL_LEGACY_SWITCH_MIMO: 1341 case IWL_LEGACY_SWITCH_MIMO2:
1370 IWL_DEBUG_HT("LQ: Legacy switch MIMO\n"); 1342 IWL_DEBUG_HT("LQ: Legacy switch MIMO\n");
1371 1343
1372 /* Set up search table to try MIMO */ 1344 /* Set up search table to try MIMO */
1373 memcpy(search_tbl, tbl, sz); 1345 memcpy(search_tbl, tbl, sz);
1374 search_tbl->lq_type = LQ_MIMO; 1346 search_tbl->lq_type = LQ_MIMO2;
1375 search_tbl->is_SGI = 0; 1347 search_tbl->is_SGI = 0;
1376 search_tbl->is_fat = 0; 1348 search_tbl->is_fat = 0;
1377 search_tbl->antenna_type = ANT_BOTH; 1349 search_tbl->ant_type = ANT_AB;/*FIXME:RS*/
1378 ret = rs_switch_to_mimo(priv, lq_sta, conf, sta, 1350 /*FIXME:RS:need to check ant validity*/
1351 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
1379 search_tbl, index); 1352 search_tbl, index);
1380 if (!ret) { 1353 if (!ret) {
1381 lq_sta->search_better_tbl = 1; 1354 lq_sta->search_better_tbl = 1;
@@ -1385,7 +1358,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1385 break; 1358 break;
1386 } 1359 }
1387 tbl->action++; 1360 tbl->action++;
1388 if (tbl->action > IWL_LEGACY_SWITCH_MIMO) 1361 if (tbl->action > IWL_LEGACY_SWITCH_MIMO2)
1389 tbl->action = IWL_LEGACY_SWITCH_ANTENNA; 1362 tbl->action = IWL_LEGACY_SWITCH_ANTENNA;
1390 1363
1391 if (tbl->action == start_action) 1364 if (tbl->action == start_action)
@@ -1396,7 +1369,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1396 1369
1397 out: 1370 out:
1398 tbl->action++; 1371 tbl->action++;
1399 if (tbl->action > IWL_LEGACY_SWITCH_MIMO) 1372 if (tbl->action > IWL_LEGACY_SWITCH_MIMO2)
1400 tbl->action = IWL_LEGACY_SWITCH_ANTENNA; 1373 tbl->action = IWL_LEGACY_SWITCH_ANTENNA;
1401 return 0; 1374 return 0;
1402 1375
@@ -1411,7 +1384,6 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1411 struct sta_info *sta, 1384 struct sta_info *sta,
1412 int index) 1385 int index)
1413{ 1386{
1414 int ret;
1415 u8 is_green = lq_sta->is_green; 1387 u8 is_green = lq_sta->is_green;
1416 struct iwl4965_scale_tbl_info *tbl = 1388 struct iwl4965_scale_tbl_info *tbl =
1417 &(lq_sta->lq_info[lq_sta->active_tbl]); 1389 &(lq_sta->lq_info[lq_sta->active_tbl]);
@@ -1421,6 +1393,8 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1421 u32 sz = (sizeof(struct iwl4965_scale_tbl_info) - 1393 u32 sz = (sizeof(struct iwl4965_scale_tbl_info) -
1422 (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT)); 1394 (sizeof(struct iwl4965_rate_scale_data) * IWL_RATE_COUNT));
1423 u8 start_action = tbl->action; 1395 u8 start_action = tbl->action;
1396 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1397 int ret;
1424 1398
1425 for (;;) { 1399 for (;;) {
1426 lq_sta->action_counter++; 1400 lq_sta->action_counter++;
@@ -1430,26 +1404,26 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1430 search_tbl->lq_type = LQ_NONE; 1404 search_tbl->lq_type = LQ_NONE;
1431 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1405 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1432 break; 1406 break;
1433 if (!rs_is_other_ant_connected(lq_sta->antenna, 1407 if (!rs_is_other_ant_connected(valid_tx_ant,
1434 tbl->antenna_type)) 1408 tbl->ant_type))
1435 break; 1409 break;
1436 1410
1437 memcpy(search_tbl, tbl, sz); 1411 memcpy(search_tbl, tbl, sz);
1438 search_tbl->action = IWL_SISO_SWITCH_MIMO; 1412 search_tbl->action = IWL_SISO_SWITCH_MIMO2;
1439 rs_toggle_antenna(&(search_tbl->current_rate), 1413 rs_toggle_antenna(&(search_tbl->current_rate),
1440 search_tbl); 1414 search_tbl);
1441 lq_sta->search_better_tbl = 1; 1415 lq_sta->search_better_tbl = 1;
1442 1416
1443 goto out; 1417 goto out;
1444 1418
1445 case IWL_SISO_SWITCH_MIMO: 1419 case IWL_SISO_SWITCH_MIMO2:
1446 IWL_DEBUG_HT("LQ: SISO SWITCH TO MIMO FROM SISO\n"); 1420 IWL_DEBUG_HT("LQ: SISO SWITCH TO MIMO2 FROM SISO\n");
1447 memcpy(search_tbl, tbl, sz); 1421 memcpy(search_tbl, tbl, sz);
1448 search_tbl->lq_type = LQ_MIMO; 1422 search_tbl->lq_type = LQ_MIMO2;
1449 search_tbl->is_SGI = 0; 1423 search_tbl->is_SGI = 0;
1450 search_tbl->is_fat = 0; 1424 search_tbl->is_fat = 0;
1451 search_tbl->antenna_type = ANT_BOTH; 1425 search_tbl->ant_type = ANT_AB; /*FIXME:RS*/
1452 ret = rs_switch_to_mimo(priv, lq_sta, conf, sta, 1426 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
1453 search_tbl, index); 1427 search_tbl, index);
1454 if (!ret) { 1428 if (!ret) {
1455 lq_sta->search_better_tbl = 1; 1429 lq_sta->search_better_tbl = 1;
@@ -1530,10 +1504,11 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
1530 search_tbl->lq_type = LQ_SISO; 1504 search_tbl->lq_type = LQ_SISO;
1531 search_tbl->is_SGI = 0; 1505 search_tbl->is_SGI = 0;
1532 search_tbl->is_fat = 0; 1506 search_tbl->is_fat = 0;
1507 /*FIXME:RS:need to check ant validity + C*/
1533 if (tbl->action == IWL_MIMO_SWITCH_ANTENNA_A) 1508 if (tbl->action == IWL_MIMO_SWITCH_ANTENNA_A)
1534 search_tbl->antenna_type = ANT_MAIN; 1509 search_tbl->ant_type = ANT_A;
1535 else 1510 else
1536 search_tbl->antenna_type = ANT_AUX; 1511 search_tbl->ant_type = ANT_B;
1537 1512
1538 ret = rs_switch_to_siso(priv, lq_sta, conf, sta, 1513 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
1539 search_tbl, index); 1514 search_tbl, index);
@@ -1548,8 +1523,6 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
1548 1523
1549 /* Set up new search table for MIMO */ 1524 /* Set up new search table for MIMO */
1550 memcpy(search_tbl, tbl, sz); 1525 memcpy(search_tbl, tbl, sz);
1551 search_tbl->lq_type = LQ_MIMO;
1552 search_tbl->antenna_type = ANT_BOTH;
1553 search_tbl->action = 0; 1526 search_tbl->action = 0;
1554 if (search_tbl->is_SGI) 1527 if (search_tbl->is_SGI)
1555 search_tbl->is_SGI = 0; 1528 search_tbl->is_SGI = 0;
@@ -1563,7 +1536,7 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
1563 * and it's working well, there's no need to look 1536 * and it's working well, there's no need to look
1564 * for a better type of modulation! 1537 * for a better type of modulation!
1565 */ 1538 */
1566 if ((tbl->lq_type == LQ_MIMO) && 1539 if ((tbl->lq_type == LQ_MIMO2) &&
1567 (tbl->is_SGI)) { 1540 (tbl->is_SGI)) {
1568 s32 tpt = lq_sta->last_tpt / 100; 1541 s32 tpt = lq_sta->last_tpt / 100;
1569 if (((!tbl->is_fat) && 1542 if (((!tbl->is_fat) &&
@@ -1830,7 +1803,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1830 /* Set up new rate table in uCode, if needed */ 1803 /* Set up new rate table in uCode, if needed */
1831 if (update_lq) { 1804 if (update_lq) {
1832 rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); 1805 rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
1833 rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); 1806 rs_fill_link_cmd(priv, lq_sta, &mcs_rate, &lq_sta->lq);
1834 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 1807 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
1835 } 1808 }
1836 goto out; 1809 goto out;
@@ -1995,7 +1968,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1995 /* Replace uCode's rate table for the destination station. */ 1968 /* Replace uCode's rate table for the destination station. */
1996 if (update_lq) { 1969 if (update_lq) {
1997 rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green); 1970 rs_mcs_from_tbl(&mcs_rate, tbl, index, is_green);
1998 rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); 1971 rs_fill_link_cmd(priv, lq_sta, &mcs_rate, &lq_sta->lq);
1999 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 1972 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
2000 } 1973 }
2001 1974
@@ -2034,7 +2007,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2034 2007
2035 IWL_DEBUG_HT("Switch current mcs: %X index: %d\n", 2008 IWL_DEBUG_HT("Switch current mcs: %X index: %d\n",
2036 tbl->current_rate.rate_n_flags, index); 2009 tbl->current_rate.rate_n_flags, index);
2037 rs_fill_link_cmd(lq_sta, &tbl->current_rate, 2010 rs_fill_link_cmd(priv, lq_sta, &tbl->current_rate,
2038 &lq_sta->lq); 2011 &lq_sta->lq);
2039 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 2012 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
2040 } 2013 }
@@ -2133,6 +2106,7 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2133 if ((i < 0) || (i >= IWL_RATE_COUNT)) 2106 if ((i < 0) || (i >= IWL_RATE_COUNT))
2134 i = 0; 2107 i = 0;
2135 2108
2109 /* FIXME:RS: This is also wrong in 4965 */
2136 mcs_rate.rate_n_flags = iwl4965_rates[i].plcp ; 2110 mcs_rate.rate_n_flags = iwl4965_rates[i].plcp ;
2137 mcs_rate.rate_n_flags |= RATE_MCS_ANT_B_MSK; 2111 mcs_rate.rate_n_flags |= RATE_MCS_ANT_B_MSK;
2138 mcs_rate.rate_n_flags &= ~RATE_MCS_ANT_A_MSK; 2112 mcs_rate.rate_n_flags &= ~RATE_MCS_ANT_A_MSK;
@@ -2140,15 +2114,15 @@ static void rs_initialize_lq(struct iwl_priv *priv,
2140 if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE) 2114 if (i >= IWL_FIRST_CCK_RATE && i <= IWL_LAST_CCK_RATE)
2141 mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK; 2115 mcs_rate.rate_n_flags |= RATE_MCS_CCK_MSK;
2142 2116
2143 tbl->antenna_type = ANT_AUX; 2117 tbl->ant_type = ANT_B;
2144 rs_get_tbl_info_from_mcs(&mcs_rate, priv->band, tbl, &rate_idx); 2118 rs_get_tbl_info_from_mcs(&mcs_rate, priv->band, tbl, &rate_idx);
2145 if (!rs_is_ant_connected(priv->valid_antenna, tbl->antenna_type)) 2119 if (!rs_is_ant_connected(priv->hw_params.valid_tx_ant, tbl->ant_type))
2146 rs_toggle_antenna(&mcs_rate, tbl); 2120 rs_toggle_antenna(&mcs_rate, tbl);
2147 2121
2148 rs_mcs_from_tbl(&mcs_rate, tbl, rate_idx, use_green); 2122 rs_mcs_from_tbl(&mcs_rate, tbl, rate_idx, use_green);
2149 tbl->current_rate.rate_n_flags = mcs_rate.rate_n_flags; 2123 tbl->current_rate.rate_n_flags = mcs_rate.rate_n_flags;
2150 rs_get_expected_tpt_table(lq_sta, tbl); 2124 rs_get_expected_tpt_table(lq_sta, tbl);
2151 rs_fill_link_cmd(lq_sta, &mcs_rate, &lq_sta->lq); 2125 rs_fill_link_cmd(NULL, lq_sta, &mcs_rate, &lq_sta->lq);
2152 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC); 2126 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
2153 out: 2127 out:
2154 return; 2128 return;
@@ -2300,8 +2274,6 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
2300 sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; 2274 sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
2301 2275
2302 lq_sta->is_dup = 0; 2276 lq_sta->is_dup = 0;
2303 lq_sta->valid_antenna = priv->valid_antenna;
2304 lq_sta->antenna = priv->antenna;
2305 lq_sta->is_green = rs_use_green(priv, conf); 2277 lq_sta->is_green = rs_use_green(priv, conf);
2306 lq_sta->active_rate = priv->active_rate; 2278 lq_sta->active_rate = priv->active_rate;
2307 lq_sta->active_rate &= ~(0x1000); 2279 lq_sta->active_rate &= ~(0x1000);
@@ -2312,23 +2284,33 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
2312 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3), 2284 * active_siso_rate mask includes 9 MBits (bit 5), and CCK (bits 0-3),
2313 * supp_rates[] does not; shift to convert format, force 9 MBits off. 2285 * supp_rates[] does not; shift to convert format, force 9 MBits off.
2314 */ 2286 */
2315 lq_sta->active_siso_rate = (priv->current_ht_config.supp_mcs_set[0] << 1); 2287 lq_sta->active_siso_rate =
2288 priv->current_ht_config.supp_mcs_set[0] << 1;
2316 lq_sta->active_siso_rate |= 2289 lq_sta->active_siso_rate |=
2317 (priv->current_ht_config.supp_mcs_set[0] & 0x1); 2290 priv->current_ht_config.supp_mcs_set[0] & 0x1;
2318 lq_sta->active_siso_rate &= ~((u16)0x2); 2291 lq_sta->active_siso_rate &= ~((u16)0x2);
2319 lq_sta->active_siso_rate = 2292 lq_sta->active_siso_rate <<= IWL_FIRST_OFDM_RATE;
2320 lq_sta->active_siso_rate << IWL_FIRST_OFDM_RATE;
2321 2293
2322 /* Same here */ 2294 /* Same here */
2323 lq_sta->active_mimo_rate = (priv->current_ht_config.supp_mcs_set[1] << 1); 2295 lq_sta->active_mimo2_rate =
2324 lq_sta->active_mimo_rate |= 2296 priv->current_ht_config.supp_mcs_set[1] << 1;
2325 (priv->current_ht_config.supp_mcs_set[1] & 0x1); 2297 lq_sta->active_mimo2_rate |=
2326 lq_sta->active_mimo_rate &= ~((u16)0x2); 2298 priv->current_ht_config.supp_mcs_set[1] & 0x1;
2327 lq_sta->active_mimo_rate = 2299 lq_sta->active_mimo2_rate &= ~((u16)0x2);
2328 lq_sta->active_mimo_rate << IWL_FIRST_OFDM_RATE; 2300 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
2329 IWL_DEBUG_HT("SISO RATE 0x%X MIMO RATE 0x%X\n", 2301
2302 lq_sta->active_mimo3_rate =
2303 priv->current_ht_config.supp_mcs_set[2] << 1;
2304 lq_sta->active_mimo3_rate |=
2305 priv->current_ht_config.supp_mcs_set[2] & 0x1;
2306 lq_sta->active_mimo3_rate &= ~((u16)0x2);
2307 lq_sta->active_mimo3_rate <<= IWL_FIRST_OFDM_RATE;
2308
2309 IWL_DEBUG_HT("SISO RATE %X MIMO2 RATE %X MIMO3 RATE %X\n",
2330 lq_sta->active_siso_rate, 2310 lq_sta->active_siso_rate,
2331 lq_sta->active_mimo_rate); 2311 lq_sta->active_mimo2_rate,
2312 lq_sta->active_mimo3_rate);
2313
2332 /* as default allow aggregation for all tids */ 2314 /* as default allow aggregation for all tids */
2333 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; 2315 lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID;
2334#endif /*CONFIG_IWL4965_HT*/ 2316#endif /*CONFIG_IWL4965_HT*/
@@ -2342,9 +2324,10 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
2342 rs_initialize_lq(priv, conf, sta); 2324 rs_initialize_lq(priv, conf, sta);
2343} 2325}
2344 2326
2345static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta, 2327static void rs_fill_link_cmd(const struct iwl_priv *priv,
2346 struct iwl4965_rate *tx_mcs, 2328 struct iwl4965_lq_sta *lq_sta,
2347 struct iwl_link_quality_cmd *lq_cmd) 2329 struct iwl4965_rate *tx_mcs,
2330 struct iwl_link_quality_cmd *lq_cmd)
2348{ 2331{
2349 int index = 0; 2332 int index = 0;
2350 int rate_idx; 2333 int rate_idx;
@@ -2376,7 +2359,8 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta,
2376 cpu_to_le32(tx_mcs->rate_n_flags); 2359 cpu_to_le32(tx_mcs->rate_n_flags);
2377 new_rate.rate_n_flags = tx_mcs->rate_n_flags; 2360 new_rate.rate_n_flags = tx_mcs->rate_n_flags;
2378 2361
2379 if (is_mimo(tbl_type.lq_type) || (tbl_type.antenna_type == ANT_MAIN)) 2362 /*FIXME:RS*/
2363 if (is_mimo(tbl_type.lq_type) || (tbl_type.ant_type == ANT_A))
2380 lq_cmd->general_params.single_stream_ant_msk 2364 lq_cmd->general_params.single_stream_ant_msk
2381 = LINK_QUAL_ANT_A_MSK; 2365 = LINK_QUAL_ANT_A_MSK;
2382 else 2366 else
@@ -2396,7 +2380,9 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta,
2396 if (ant_toggle_count < 2380 if (ant_toggle_count <
2397 NUM_TRY_BEFORE_ANTENNA_TOGGLE) 2381 NUM_TRY_BEFORE_ANTENNA_TOGGLE)
2398 ant_toggle_count++; 2382 ant_toggle_count++;
2399 else { 2383 else if (priv && rs_is_other_ant_connected(
2384 priv->hw_params.valid_tx_ant,
2385 tbl_type.ant_type)) {
2400 rs_toggle_antenna(&new_rate, &tbl_type); 2386 rs_toggle_antenna(&new_rate, &tbl_type);
2401 ant_toggle_count = 1; 2387 ant_toggle_count = 1;
2402 } 2388 }
@@ -2429,7 +2415,9 @@ static void rs_fill_link_cmd(struct iwl4965_lq_sta *lq_sta,
2429 if (is_legacy(tbl_type.lq_type)) { 2415 if (is_legacy(tbl_type.lq_type)) {
2430 if (ant_toggle_count < NUM_TRY_BEFORE_ANTENNA_TOGGLE) 2416 if (ant_toggle_count < NUM_TRY_BEFORE_ANTENNA_TOGGLE)
2431 ant_toggle_count++; 2417 ant_toggle_count++;
2432 else { 2418 else if (priv && rs_is_other_ant_connected(
2419 priv->hw_params.valid_tx_ant,
2420 tbl_type.ant_type)) {
2433 rs_toggle_antenna(&new_rate, &tbl_type); 2421 rs_toggle_antenna(&new_rate, &tbl_type);
2434 ant_toggle_count = 1; 2422 ant_toggle_count = 1;
2435 } 2423 }
@@ -2536,13 +2524,14 @@ static ssize_t rs_sta_dbgfs_scale_table_write(struct file *file,
2536 2524
2537 lq_sta->active_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */ 2525 lq_sta->active_rate = 0x0FFF; /* 1 - 54 MBits, includes CCK */
2538 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ 2526 lq_sta->active_siso_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
2539 lq_sta->active_mimo_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ 2527 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 */
2540 2529
2541 IWL_DEBUG_RATE("sta_id %d rate 0x%X\n", 2530 IWL_DEBUG_RATE("sta_id %d rate 0x%X\n",
2542 lq_sta->lq.sta_id, lq_sta->dbg_fixed.rate_n_flags); 2531 lq_sta->lq.sta_id, lq_sta->dbg_fixed.rate_n_flags);
2543 2532
2544 if (lq_sta->dbg_fixed.rate_n_flags) { 2533 if (lq_sta->dbg_fixed.rate_n_flags) {
2545 rs_fill_link_cmd(lq_sta, &lq_sta->dbg_fixed, &lq_sta->lq); 2534 rs_fill_link_cmd(NULL, lq_sta, &lq_sta->dbg_fixed, &lq_sta->lq);
2546 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC); 2535 iwl_send_lq_cmd(lq_sta->drv, &lq_sta->lq, CMD_ASYNC);
2547 } 2536 }
2548 2537
@@ -2703,7 +2692,7 @@ int iwl4965_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id)
2703 lq_sta = (void *)sta->rate_ctrl_priv; 2692 lq_sta = (void *)sta->rate_ctrl_priv;
2704 2693
2705 lq_type = lq_sta->lq_info[lq_sta->active_tbl].lq_type; 2694 lq_type = lq_sta->lq_info[lq_sta->active_tbl].lq_type;
2706 antenna = lq_sta->lq_info[lq_sta->active_tbl].antenna_type; 2695 antenna = lq_sta->lq_info[lq_sta->active_tbl].ant_type;
2707 2696
2708 if (is_legacy(lq_type)) 2697 if (is_legacy(lq_type))
2709 i = IWL_RATE_54M_INDEX; 2698 i = IWL_RATE_54M_INDEX;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
index 866e378aa385..f6793203515d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965-rs.h
@@ -32,7 +32,8 @@
32struct iwl4965_rate_info { 32struct iwl4965_rate_info {
33 u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */ 33 u8 plcp; /* uCode API: IWL_RATE_6M_PLCP, etc. */
34 u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */ 34 u8 plcp_siso; /* uCode API: IWL_RATE_SISO_6M_PLCP, etc. */
35 u8 plcp_mimo; /* uCode API: IWL_RATE_MIMO_6M_PLCP, etc. */ 35 u8 plcp_mimo2; /* uCode API: IWL_RATE_MIMO2_6M_PLCP, etc. */
36 u8 plcp_mimo3; /* uCode API: IWL_RATE_MIMO3_6M_PLCP, etc. */
36 u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */ 37 u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
37 u8 prev_ieee; /* previous rate in IEEE speeds */ 38 u8 prev_ieee; /* previous rate in IEEE speeds */
38 u8 next_ieee; /* next rate in IEEE speeds */ 39 u8 next_ieee; /* next rate in IEEE speeds */
@@ -60,9 +61,9 @@ enum {
60 IWL_RATE_48M_INDEX, 61 IWL_RATE_48M_INDEX,
61 IWL_RATE_54M_INDEX, 62 IWL_RATE_54M_INDEX,
62 IWL_RATE_60M_INDEX, 63 IWL_RATE_60M_INDEX,
63 IWL_RATE_COUNT, 64 IWL_RATE_COUNT, /*FIXME:RS:change to IWL_RATE_INDEX_COUNT,*/
64 IWL_RATE_INVM_INDEX = IWL_RATE_COUNT, 65 IWL_RATE_INVM_INDEX = IWL_RATE_COUNT,
65 IWL_RATE_INVALID = IWL_RATE_INVM_INDEX 66 IWL_RATE_INVALID = IWL_RATE_COUNT,
66}; 67};
67 68
68enum { 69enum {
@@ -97,11 +98,13 @@ enum {
97 IWL_RATE_36M_PLCP = 11, 98 IWL_RATE_36M_PLCP = 11,
98 IWL_RATE_48M_PLCP = 1, 99 IWL_RATE_48M_PLCP = 1,
99 IWL_RATE_54M_PLCP = 3, 100 IWL_RATE_54M_PLCP = 3,
100 IWL_RATE_60M_PLCP = 3, 101 IWL_RATE_60M_PLCP = 3,/*FIXME:RS:should be removed*/
101 IWL_RATE_1M_PLCP = 10, 102 IWL_RATE_1M_PLCP = 10,
102 IWL_RATE_2M_PLCP = 20, 103 IWL_RATE_2M_PLCP = 20,
103 IWL_RATE_5M_PLCP = 55, 104 IWL_RATE_5M_PLCP = 55,
104 IWL_RATE_11M_PLCP = 110, 105 IWL_RATE_11M_PLCP = 110,
106 /*FIXME:RS:change to IWL_RATE_LEGACY_??M_PLCP */
107 /*FIXME:RS:add IWL_RATE_LEGACY_INVM_PLCP = 0,*/
105}; 108};
106 109
107/* 4965 uCode API values for OFDM high-throughput (HT) bit rates */ 110/* 4965 uCode API values for OFDM high-throughput (HT) bit rates */
@@ -114,16 +117,25 @@ enum {
114 IWL_RATE_SISO_48M_PLCP = 5, 117 IWL_RATE_SISO_48M_PLCP = 5,
115 IWL_RATE_SISO_54M_PLCP = 6, 118 IWL_RATE_SISO_54M_PLCP = 6,
116 IWL_RATE_SISO_60M_PLCP = 7, 119 IWL_RATE_SISO_60M_PLCP = 7,
117 IWL_RATE_MIMO_6M_PLCP = 0x8, 120 IWL_RATE_MIMO2_6M_PLCP = 0x8,
118 IWL_RATE_MIMO_12M_PLCP = 0x9, 121 IWL_RATE_MIMO2_12M_PLCP = 0x9,
119 IWL_RATE_MIMO_18M_PLCP = 0xa, 122 IWL_RATE_MIMO2_18M_PLCP = 0xa,
120 IWL_RATE_MIMO_24M_PLCP = 0xb, 123 IWL_RATE_MIMO2_24M_PLCP = 0xb,
121 IWL_RATE_MIMO_36M_PLCP = 0xc, 124 IWL_RATE_MIMO2_36M_PLCP = 0xc,
122 IWL_RATE_MIMO_48M_PLCP = 0xd, 125 IWL_RATE_MIMO2_48M_PLCP = 0xd,
123 IWL_RATE_MIMO_54M_PLCP = 0xe, 126 IWL_RATE_MIMO2_54M_PLCP = 0xe,
124 IWL_RATE_MIMO_60M_PLCP = 0xf, 127 IWL_RATE_MIMO2_60M_PLCP = 0xf,
128 IWL_RATE_MIMO3_6M_PLCP = 0x10,
129 IWL_RATE_MIMO3_12M_PLCP = 0x11,
130 IWL_RATE_MIMO3_18M_PLCP = 0x12,
131 IWL_RATE_MIMO3_24M_PLCP = 0x13,
132 IWL_RATE_MIMO3_36M_PLCP = 0x14,
133 IWL_RATE_MIMO3_48M_PLCP = 0x15,
134 IWL_RATE_MIMO3_54M_PLCP = 0x16,
135 IWL_RATE_MIMO3_60M_PLCP = 0x17,
125 IWL_RATE_SISO_INVM_PLCP, 136 IWL_RATE_SISO_INVM_PLCP,
126 IWL_RATE_MIMO_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP, 137 IWL_RATE_MIMO2_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP,
138 IWL_RATE_MIMO3_INVM_PLCP = IWL_RATE_SISO_INVM_PLCP,
127}; 139};
128 140
129/* MAC header values for bit rates */ 141/* MAC header values for bit rates */
@@ -196,11 +208,11 @@ enum {
196/* possible actions when in legacy mode */ 208/* possible actions when in legacy mode */
197#define IWL_LEGACY_SWITCH_ANTENNA 0 209#define IWL_LEGACY_SWITCH_ANTENNA 0
198#define IWL_LEGACY_SWITCH_SISO 1 210#define IWL_LEGACY_SWITCH_SISO 1
199#define IWL_LEGACY_SWITCH_MIMO 2 211#define IWL_LEGACY_SWITCH_MIMO2 2
200 212
201/* possible actions when in siso mode */ 213/* possible actions when in siso mode */
202#define IWL_SISO_SWITCH_ANTENNA 0 214#define IWL_SISO_SWITCH_ANTENNA 0
203#define IWL_SISO_SWITCH_MIMO 1 215#define IWL_SISO_SWITCH_MIMO2 1
204#define IWL_SISO_SWITCH_GI 2 216#define IWL_SISO_SWITCH_GI 2
205 217
206/* possible actions when in mimo mode */ 218/* possible actions when in mimo mode */
@@ -208,6 +220,10 @@ enum {
208#define IWL_MIMO_SWITCH_ANTENNA_B 1 220#define IWL_MIMO_SWITCH_ANTENNA_B 1
209#define IWL_MIMO_SWITCH_GI 2 221#define IWL_MIMO_SWITCH_GI 2
210 222
223/*FIXME:RS:separate MIMO2/3 transitions*/
224
225/*FIXME:RS:add posible acctions for MIMO3*/
226
211#define IWL_ACTION_LIMIT 3 /* # possible actions */ 227#define IWL_ACTION_LIMIT 3 /* # possible actions */
212 228
213#define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */ 229#define LQ_SIZE 2 /* 2 mode tables: "Active" and "Search" */
@@ -226,29 +242,40 @@ enum {
226 242
227extern const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT]; 243extern const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT];
228 244
229enum iwl4965_table_type { 245enum iwl_table_type {
230 LQ_NONE, 246 LQ_NONE,
231 LQ_G, /* legacy types */ 247 LQ_G, /* legacy types */
232 LQ_A, 248 LQ_A,
233 LQ_SISO, /* high-throughput types */ 249 LQ_SISO, /* high-throughput types */
234 LQ_MIMO, 250 LQ_MIMO2,
251 LQ_MIMO3,
235 LQ_MAX, 252 LQ_MAX,
236}; 253};
237 254
238#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A)) 255#define is_legacy(tbl) (((tbl) == LQ_G) || ((tbl) == LQ_A))
239#define is_siso(tbl) (((tbl) == LQ_SISO)) 256#define is_siso(tbl) ((tbl) == LQ_SISO)
240#define is_mimo(tbl) (((tbl) == LQ_MIMO)) 257#define is_mimo2(tbl) ((tbl) == LQ_MIMO2)
258#define is_mimo3(tbl) ((tbl) == LQ_MIMO3)
259#define is_mimo(tbl) (is_mimo2(tbl) || is_mimo3(tbl))
241#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl)) 260#define is_Ht(tbl) (is_siso(tbl) || is_mimo(tbl))
242#define is_a_band(tbl) (((tbl) == LQ_A)) 261#define is_a_band(tbl) ((tbl) == LQ_A)
243#define is_g_and(tbl) (((tbl) == LQ_G)) 262#define is_g_and(tbl) ((tbl) == LQ_G)
244 263
245/* 4965 has 2 antennas/chains for Tx (but 3 for Rx) */ 264#define ANT_NONE 0x0
246enum iwl4965_antenna_type { 265#define ANT_A BIT(0)
247 ANT_NONE, 266#define ANT_B BIT(1)
248 ANT_MAIN, 267#define ANT_AB (ANT_A | ANT_B)
249 ANT_AUX, 268#define ANT_C BIT(2)
250 ANT_BOTH, 269#define ANT_AC (ANT_A | ANT_C)
251}; 270#define ANT_BC (ANT_B | ANT_C)
271#define ANT_ABC (ANT_AB | ANT_C)
272
273static inline u8 num_of_ant(u8 mask)
274{
275 return !!((mask) & ANT_A) +
276 !!((mask) & ANT_B) +
277 !!((mask) & ANT_C);
278}
252 279
253static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index) 280static inline u8 iwl4965_get_prev_ieee_rate(u8 rate_index)
254{ 281{
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 91cc03f76e1a..2c5bfa4f048d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -58,7 +58,8 @@ static void iwl4965_hw_card_show_info(struct iwl_priv *priv);
58#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \ 58#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
59 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \ 59 [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
60 IWL_RATE_SISO_##s##M_PLCP, \ 60 IWL_RATE_SISO_##s##M_PLCP, \
61 IWL_RATE_MIMO_##s##M_PLCP, \ 61 IWL_RATE_MIMO2_##s##M_PLCP,\
62 IWL_RATE_MIMO3_##s##M_PLCP,\
62 IWL_RATE_##r##M_IEEE, \ 63 IWL_RATE_##r##M_IEEE, \
63 IWL_RATE_##ip##M_INDEX, \ 64 IWL_RATE_##ip##M_INDEX, \
64 IWL_RATE_##in##M_INDEX, \ 65 IWL_RATE_##in##M_INDEX, \
@@ -89,6 +90,7 @@ const struct iwl4965_rate_info iwl4965_rates[IWL_RATE_COUNT] = {
89 IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */ 90 IWL_DECLARE_RATE_INFO(48, 48, 36, 54, 36, 54, 36, 54), /* 48mbps */
90 IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */ 91 IWL_DECLARE_RATE_INFO(54, 54, 48, INV, 48, INV, 48, INV),/* 54mbps */
91 IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */ 92 IWL_DECLARE_RATE_INFO(60, 60, 48, INV, 48, INV, 48, INV),/* 60mbps */
93 /* FIXME:RS: ^^ should be INV (legacy) */
92}; 94};
93 95
94#ifdef CONFIG_IWL4965_HT 96#ifdef CONFIG_IWL4965_HT
@@ -265,7 +267,6 @@ static int iwl4965_init_drv(struct iwl_priv *priv)
265 int ret; 267 int ret;
266 int i; 268 int i;
267 269
268 priv->antenna = (enum iwl4965_antenna)priv->cfg->mod_params->antenna;
269 priv->retry_rate = 1; 270 priv->retry_rate = 1;
270 priv->ibss_beacon = NULL; 271 priv->ibss_beacon = NULL;
271 272
@@ -305,7 +306,6 @@ static int iwl4965_init_drv(struct iwl_priv *priv)
305 priv->iw_mode = IEEE80211_IF_TYPE_STA; 306 priv->iw_mode = IEEE80211_IF_TYPE_STA;
306 307
307 priv->use_ant_b_for_management_frame = 1; /* start with ant B */ 308 priv->use_ant_b_for_management_frame = 1; /* start with ant B */
308 priv->valid_antenna = 0x7; /* assume all 3 connected */
309 priv->ps_mode = IWL_MIMO_PS_NONE; 309 priv->ps_mode = IWL_MIMO_PS_NONE;
310 310
311 /* Choose which receivers/antennas to use */ 311 /* Choose which receivers/antennas to use */
@@ -361,18 +361,20 @@ static int is_fat_channel(__le32 rxon_flags)
361 (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK); 361 (rxon_flags & RXON_FLG_CHANNEL_MODE_MIXED_MSK);
362} 362}
363 363
364static u8 is_single_stream(struct iwl_priv *priv)
365{
366#ifdef CONFIG_IWL4965_HT 364#ifdef CONFIG_IWL4965_HT
367 if (!priv->current_ht_config.is_ht || 365static u8 is_single_rx_stream(struct iwl_priv *priv)
368 (priv->current_ht_config.supp_mcs_set[1] == 0) || 366{
369 (priv->ps_mode == IWL_MIMO_PS_STATIC)) 367 return !priv->current_ht_config.is_ht ||
370 return 1; 368 ((priv->current_ht_config.supp_mcs_set[1] == 0) &&
369 (priv->current_ht_config.supp_mcs_set[2] == 0)) ||
370 priv->ps_mode == IWL_MIMO_PS_STATIC;
371}
371#else 372#else
373static inline u8 is_single_rx_stream(struct iwl_priv *priv)
374{
372 return 1; 375 return 1;
373#endif /*CONFIG_IWL4965_HT */
374 return 0;
375} 376}
377#endif /*CONFIG_IWL4965_HT */
376 378
377int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags) 379int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags)
378{ 380{
@@ -382,8 +384,8 @@ int iwl4965_hwrate_to_plcp_idx(u32 rate_n_flags)
382 if (rate_n_flags & RATE_MCS_HT_MSK) { 384 if (rate_n_flags & RATE_MCS_HT_MSK) {
383 idx = (rate_n_flags & 0xff); 385 idx = (rate_n_flags & 0xff);
384 386
385 if (idx >= IWL_RATE_MIMO_6M_PLCP) 387 if (idx >= IWL_RATE_MIMO2_6M_PLCP)
386 idx = idx - IWL_RATE_MIMO_6M_PLCP; 388 idx = idx - IWL_RATE_MIMO2_6M_PLCP;
387 389
388 idx += IWL_FIRST_OFDM_RATE; 390 idx += IWL_FIRST_OFDM_RATE;
389 /* skip 9M not supported in ht*/ 391 /* skip 9M not supported in ht*/
@@ -411,7 +413,7 @@ void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
411 int rate_index; 413 int rate_index;
412 414
413 control->antenna_sel_tx = 415 control->antenna_sel_tx =
414 ((rate_n_flags & RATE_MCS_ANT_AB_MSK) >> RATE_MCS_ANT_POS); 416 ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
415 if (rate_n_flags & RATE_MCS_HT_MSK) 417 if (rate_n_flags & RATE_MCS_HT_MSK)
416 control->flags |= IEEE80211_TXCTL_OFDM_HT; 418 control->flags |= IEEE80211_TXCTL_OFDM_HT;
417 if (rate_n_flags & RATE_MCS_GF_MSK) 419 if (rate_n_flags & RATE_MCS_GF_MSK)
@@ -441,7 +443,7 @@ void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
441static int iwl4965_get_rx_chain_counter(struct iwl_priv *priv, 443static int iwl4965_get_rx_chain_counter(struct iwl_priv *priv,
442 u8 *idle_state, u8 *rx_state) 444 u8 *idle_state, u8 *rx_state)
443{ 445{
444 u8 is_single = is_single_stream(priv); 446 u8 is_single = is_single_rx_stream(priv);
445 u8 is_cam = test_bit(STATUS_POWER_PMI, &priv->status) ? 0 : 1; 447 u8 is_cam = test_bit(STATUS_POWER_PMI, &priv->status) ? 0 : 1;
446 448
447 /* # of Rx chains to use when expecting MIMO. */ 449 /* # of Rx chains to use when expecting MIMO. */
@@ -1344,8 +1346,8 @@ int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
1344 1346
1345 priv->hw_params.tx_chains_num = 2; 1347 priv->hw_params.tx_chains_num = 2;
1346 priv->hw_params.rx_chains_num = 2; 1348 priv->hw_params.rx_chains_num = 2;
1347 priv->hw_params.valid_tx_ant = (IWL_ANTENNA_MAIN | IWL_ANTENNA_AUX); 1349 priv->hw_params.valid_tx_ant = ANT_A | ANT_B;
1348 priv->hw_params.valid_rx_ant = (IWL_ANTENNA_MAIN | IWL_ANTENNA_AUX); 1350 priv->hw_params.valid_rx_ant = ANT_A | ANT_B;
1349 priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD); 1351 priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD);
1350 1352
1351#ifdef CONFIG_IWL4965_RUN_TIME_CALIB 1353#ifdef CONFIG_IWL4965_RUN_TIME_CALIB
@@ -2512,7 +2514,7 @@ static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
2512 */ 2514 */
2513void iwl4965_set_rxon_chain(struct iwl_priv *priv) 2515void iwl4965_set_rxon_chain(struct iwl_priv *priv)
2514{ 2516{
2515 u8 is_single = is_single_stream(priv); 2517 u8 is_single = is_single_rx_stream(priv);
2516 u8 idle_state, rx_state; 2518 u8 idle_state, rx_state;
2517 2519
2518 priv->staging_rxon.rx_chain = 0; 2520 priv->staging_rxon.rx_chain = 0;
@@ -2523,7 +2525,8 @@ void iwl4965_set_rxon_chain(struct iwl_priv *priv)
2523 * Just after first association, iwl_chain_noise_calibration() 2525 * Just after first association, iwl_chain_noise_calibration()
2524 * checks which antennas actually *are* connected. */ 2526 * checks which antennas actually *are* connected. */
2525 priv->staging_rxon.rx_chain |= 2527 priv->staging_rxon.rx_chain |=
2526 cpu_to_le16(priv->valid_antenna << RXON_RX_CHAIN_VALID_POS); 2528 cpu_to_le16(priv->hw_params.valid_rx_ant <<
2529 RXON_RX_CHAIN_VALID_POS);
2527 2530
2528 /* How many receivers should we use? */ 2531 /* How many receivers should we use? */
2529 iwl4965_get_rx_chain_counter(priv, &idle_state, &rx_state); 2532 iwl4965_get_rx_chain_counter(priv, &idle_state, &rx_state);
@@ -3106,7 +3109,7 @@ static int iwl4965_calc_rssi(struct iwl4965_rx_phy_res *rx_resp)
3106 3109
3107#ifdef CONFIG_IWL4965_HT 3110#ifdef CONFIG_IWL4965_HT
3108 3111
3109void iwl4965_init_ht_hw_capab(struct iwl_priv *priv, 3112void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv,
3110 struct ieee80211_ht_info *ht_info, 3113 struct ieee80211_ht_info *ht_info,
3111 enum ieee80211_band band) 3114 enum ieee80211_band band)
3112{ 3115{
@@ -3132,7 +3135,10 @@ void iwl4965_init_ht_hw_capab(struct iwl_priv *priv,
3132 ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF; 3135 ht_info->ampdu_density = CFG_HT_MPDU_DENSITY_DEF;
3133 3136
3134 ht_info->supp_mcs_set[0] = 0xFF; 3137 ht_info->supp_mcs_set[0] = 0xFF;
3135 ht_info->supp_mcs_set[1] = 0xFF; 3138 if (priv->hw_params.tx_chains_num >= 2)
3139 ht_info->supp_mcs_set[1] = 0xFF;
3140 if (priv->hw_params.tx_chains_num >= 3)
3141 ht_info->supp_mcs_set[2] = 0xFF;
3136} 3142}
3137#endif /* CONFIG_IWL4965_HT */ 3143#endif /* CONFIG_IWL4965_HT */
3138 3144
@@ -3910,8 +3916,7 @@ void iwl4965_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap)
3910 rate_flags |= RATE_MCS_CCK_MSK; 3916 rate_flags |= RATE_MCS_CCK_MSK;
3911 3917
3912 /* Use Tx antenna B only */ 3918 /* Use Tx antenna B only */
3913 rate_flags |= RATE_MCS_ANT_B_MSK; 3919 rate_flags |= RATE_MCS_ANT_B_MSK; /*FIXME:RS*/
3914 rate_flags &= ~RATE_MCS_ANT_A_MSK;
3915 3920
3916 link_cmd.rs_table[i].rate_n_flags = 3921 link_cmd.rs_table[i].rate_n_flags =
3917 iwl4965_hw_set_rate_n_flags(iwl4965_rates[r].plcp, rate_flags); 3922 iwl4965_hw_set_rate_n_flags(iwl4965_rates[r].plcp, rate_flags);
@@ -4016,11 +4021,13 @@ void iwl4965_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info)
4016 4021
4017 iwl4965_set_rxon_chain(priv); 4022 iwl4965_set_rxon_chain(priv);
4018 4023
4019 IWL_DEBUG_ASSOC("supported HT rate 0x%X %X " 4024 IWL_DEBUG_ASSOC("supported HT rate 0x%X 0x%X 0x%X "
4020 "rxon flags 0x%X operation mode :0x%X " 4025 "rxon flags 0x%X operation mode :0x%X "
4021 "extension channel offset 0x%x " 4026 "extension channel offset 0x%x "
4022 "control chan %d\n", 4027 "control chan %d\n",
4023 ht_info->supp_mcs_set[0], ht_info->supp_mcs_set[1], 4028 ht_info->supp_mcs_set[0],
4029 ht_info->supp_mcs_set[1],
4030 ht_info->supp_mcs_set[2],
4024 le32_to_cpu(rxon->flags), ht_info->ht_protection, 4031 le32_to_cpu(rxon->flags), ht_info->ht_protection,
4025 ht_info->extension_chan_offset, 4032 ht_info->extension_chan_offset,
4026 ht_info->control_channel); 4033 ht_info->control_channel);
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.h b/drivers/net/wireless/iwlwifi/iwl-4965.h
index 07209f85cb5f..6df51cca2289 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.h
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.h
@@ -71,12 +71,6 @@ extern struct iwl_cfg iwl4965_agn_cfg;
71 * averages within an s8's (used in some apps) range of negative values. */ 71 * averages within an s8's (used in some apps) range of negative values. */
72#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127) 72#define IWL_NOISE_MEAS_NOT_AVAILABLE (-127)
73 73
74enum iwl4965_antenna {
75 IWL_ANTENNA_DIVERSITY,
76 IWL_ANTENNA_MAIN,
77 IWL_ANTENNA_AUX
78};
79
80/* 74/*
81 * RTS threshold here is total size [2347] minus 4 FCS bytes 75 * RTS threshold here is total size [2347] minus 4 FCS bytes
82 * Per spec: 76 * Per spec:
@@ -763,9 +757,9 @@ extern void iwl4965_hwrate_to_tx_control(struct iwl_priv *priv,
763 struct ieee80211_tx_control *control); 757 struct ieee80211_tx_control *control);
764 758
765#ifdef CONFIG_IWL4965_HT 759#ifdef CONFIG_IWL4965_HT
766void iwl4965_init_ht_hw_capab(struct iwl_priv *priv, 760extern void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv,
767 struct ieee80211_ht_info *ht_info, 761 struct ieee80211_ht_info *ht_info,
768 enum ieee80211_band band); 762 enum ieee80211_band band);
769void iwl4965_set_rxon_ht(struct iwl_priv *priv, 763void iwl4965_set_rxon_ht(struct iwl_priv *priv,
770 struct iwl_ht_info *ht_info); 764 struct iwl_ht_info *ht_info);
771void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index, 765void iwl4965_set_ht_add_station(struct iwl_priv *priv, u8 index,
@@ -776,7 +770,7 @@ int iwl4965_mac_ampdu_action(struct ieee80211_hw *hw,
776int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id, 770int iwl4965_check_empty_hw_queue(struct iwl_priv *priv, int sta_id,
777 u8 tid, int txq_id); 771 u8 tid, int txq_id);
778#else 772#else
779static inline void iwl4965_init_ht_hw_capab(struct iwl_priv *priv, 773static inline void iwl4965_init_ht_hw_capab(const struct iwl_priv *priv,
780 struct ieee80211_ht_info *ht_info, 774 struct ieee80211_ht_info *ht_info,
781 enum ieee80211_band band) {} 775 enum ieee80211_band band) {}
782 776
@@ -1052,7 +1046,6 @@ struct iwl_priv {
1052 1046
1053 u8 assoc_station_added; 1047 u8 assoc_station_added;
1054 u8 use_ant_b_for_management_frame; /* Tx antenna selection */ 1048 u8 use_ant_b_for_management_frame; /* Tx antenna selection */
1055 u8 valid_antenna; /* Bit mask of antennas actually connected */
1056 u8 start_calib; 1049 u8 start_calib;
1057#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB 1050#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
1058 struct iwl_sensitivity_data sensitivity_data; 1051 struct iwl_sensitivity_data sensitivity_data;
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index 16213b05ed93..59bbd7c9636f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -747,7 +747,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
747 active_chains); 747 active_chains);
748 748
749 /* Save for use within RXON, TX, SCAN commands, etc. */ 749 /* Save for use within RXON, TX, SCAN commands, etc. */
750 priv->valid_antenna = active_chains; 750 /*priv->valid_antenna = active_chains;*/
751 /*FIXME: should be reflected in RX chains in RXON */
751 752
752 /* Analyze noise for rx balance */ 753 /* Analyze noise for rx balance */
753 average_noise[0] = ((data->chain_noise_a)/CAL_NUM_OF_BEACONS); 754 average_noise[0] = ((data->chain_noise_a)/CAL_NUM_OF_BEACONS);
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c
index 4bfc670e8784..1f5e7e6fa687 100644
--- a/drivers/net/wireless/iwlwifi/iwl4965-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c
@@ -7242,44 +7242,6 @@ static ssize_t show_statistics(struct device *d,
7242 7242
7243static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL); 7243static DEVICE_ATTR(statistics, S_IRUGO, show_statistics, NULL);
7244 7244
7245static ssize_t show_antenna(struct device *d,
7246 struct device_attribute *attr, char *buf)
7247{
7248 struct iwl_priv *priv = dev_get_drvdata(d);
7249
7250 if (!iwl_is_alive(priv))
7251 return -EAGAIN;
7252
7253 return sprintf(buf, "%d\n", priv->antenna);
7254}
7255
7256static ssize_t store_antenna(struct device *d,
7257 struct device_attribute *attr,
7258 const char *buf, size_t count)
7259{
7260 int ant;
7261 struct iwl_priv *priv = dev_get_drvdata(d);
7262
7263 if (count == 0)
7264 return 0;
7265
7266 if (sscanf(buf, "%1i", &ant) != 1) {
7267 IWL_DEBUG_INFO("not in hex or decimal form.\n");
7268 return count;
7269 }
7270
7271 if ((ant >= 0) && (ant <= 2)) {
7272 IWL_DEBUG_INFO("Setting antenna select to %d.\n", ant);
7273 priv->antenna = (enum iwl4965_antenna)ant;
7274 } else
7275 IWL_DEBUG_INFO("Bad antenna select value %d.\n", ant);
7276
7277
7278 return count;
7279}
7280
7281static DEVICE_ATTR(antenna, S_IWUSR | S_IRUGO, show_antenna, store_antenna);
7282
7283static ssize_t show_status(struct device *d, 7245static ssize_t show_status(struct device *d,
7284 struct device_attribute *attr, char *buf) 7246 struct device_attribute *attr, char *buf)
7285{ 7247{
@@ -7362,7 +7324,6 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
7362} 7324}
7363 7325
7364static struct attribute *iwl4965_sysfs_entries[] = { 7326static struct attribute *iwl4965_sysfs_entries[] = {
7365 &dev_attr_antenna.attr,
7366 &dev_attr_channels.attr, 7327 &dev_attr_channels.attr,
7367 &dev_attr_dump_errors.attr, 7328 &dev_attr_dump_errors.attr,
7368 &dev_attr_dump_events.attr, 7329 &dev_attr_dump_events.attr,