aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-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,