aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k
diff options
context:
space:
mode:
authorSujith <Sujith.Manoharan@atheros.com>2008-11-17 22:38:33 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-11-26 09:47:32 -0500
commit2c5a744d43a6a08666930906742fbe704739ba6f (patch)
treea1de6a3535f62b26dc0104f451dd3ed87ab4dd08 /drivers/net/wireless/ath9k
parent46d14a58ffb42702e4c1b8bb88cfa05414617f4c (diff)
ath9k: Use helpers
Break down huge functions, use helper functions or macros instead. Signed-off-by: Sujith <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath9k')
-rw-r--r--drivers/net/wireless/ath9k/rc.c386
-rw-r--r--drivers/net/wireless/ath9k/rc.h5
2 files changed, 194 insertions, 197 deletions
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
index 51f51afa6da9..e118824625ba 100644
--- a/drivers/net/wireless/ath9k/rc.c
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -153,11 +153,6 @@ static struct ath_rate_table ar5416_11na_ratetable = {
153 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 153 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
154}; 154};
155 155
156/* VALID_ALL - valid for 20/40/Legacy,
157 * VALID - Legacy only,
158 * VALID_20 - HT 20 only,
159 * VALID_40 - HT 40 only */
160
161/* 4ms frame limit not used for NG mode. The values filled 156/* 4ms frame limit not used for NG mode. The values filled
162 * for HT are the 64K max aggregate limit */ 157 * for HT are the 64K max aggregate limit */
163 158
@@ -471,11 +466,10 @@ static inline int ath_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv,
471 return ath_rc_priv->valid_rate_index[index]; 466 return ath_rc_priv->valid_rate_index[index];
472} 467}
473 468
474static inline int 469static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
475ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table, 470 struct ath_rate_priv *ath_rc_priv,
476 struct ath_rate_priv *ath_rc_priv, 471 u8 cur_valid_txrate,
477 u8 cur_valid_txrate, 472 u8 *next_idx)
478 u8 *next_idx)
479{ 473{
480 u8 i; 474 u8 i;
481 475
@@ -488,6 +482,7 @@ ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
488 482
489 /* No more valid rates */ 483 /* No more valid rates */
490 *next_idx = 0; 484 *next_idx = 0;
485
491 return 0; 486 return 0;
492} 487}
493 488
@@ -522,13 +517,13 @@ ath_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table,
522 return 1; 517 return 1;
523 } 518 }
524 } 519 }
520
525 return 0; 521 return 0;
526} 522}
527 523
528static u8 524static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
529ath_rc_sib_init_validrates(struct ath_rate_priv *ath_rc_priv, 525 struct ath_rate_table *rate_table,
530 struct ath_rate_table *rate_table, 526 u32 capflag)
531 u32 capflag)
532{ 527{
533 u8 i, hi = 0; 528 u8 i, hi = 0;
534 u32 valid; 529 u32 valid;
@@ -552,14 +547,14 @@ ath_rc_sib_init_validrates(struct ath_rate_priv *ath_rc_priv,
552 hi = A_MAX(hi, i); 547 hi = A_MAX(hi, i);
553 } 548 }
554 } 549 }
550
555 return hi; 551 return hi;
556} 552}
557 553
558static u8 554static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
559ath_rc_sib_setvalid_rates(struct ath_rate_priv *ath_rc_priv, 555 struct ath_rate_table *rate_table,
560 struct ath_rate_table *rate_table, 556 struct ath_rateset *rateset,
561 struct ath_rateset *rateset, 557 u32 capflag)
562 u32 capflag)
563{ 558{
564 u8 i, j, hi = 0; 559 u8 i, j, hi = 0;
565 560
@@ -570,17 +565,17 @@ ath_rc_sib_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
570 u32 valid = (ath_rc_priv->single_stream ? 565 u32 valid = (ath_rc_priv->single_stream ?
571 rate_table->info[j].valid_single_stream : 566 rate_table->info[j].valid_single_stream :
572 rate_table->info[j].valid); 567 rate_table->info[j].valid);
568 u8 rate = rateset->rs_rates[i];
569 u8 dot11rate = rate_table->info[j].dot11rate;
573 570
574 /* We allow a rate only if its valid and the 571 /* We allow a rate only if its valid and the
575 * capflag matches one of the validity 572 * capflag matches one of the validity
576 * (VALID/VALID_20/VALID_40) flags */ 573 * (VALID/VALID_20/VALID_40) flags */
577 574
578 if (((rateset->rs_rates[i] & 0x7F) == 575 if (((rate & 0x7F) == (dot11rate & 0x7F)) &&
579 (rate_table->info[j].dot11rate & 0x7F)) && 576 ((valid & WLAN_RC_CAP_MODE(capflag)) ==
580 ((valid & WLAN_RC_CAP_MODE(capflag)) == 577 WLAN_RC_CAP_MODE(capflag)) &&
581 WLAN_RC_CAP_MODE(capflag)) && 578 !WLAN_RC_PHY_HT(phy)) {
582 !WLAN_RC_PHY_HT(phy)) {
583
584 u8 valid_rate_count = 0; 579 u8 valid_rate_count = 0;
585 580
586 if (!ath_rc_valid_phyrate(phy, capflag, 0)) 581 if (!ath_rc_valid_phyrate(phy, capflag, 0))
@@ -597,27 +592,29 @@ ath_rc_sib_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
597 } 592 }
598 } 593 }
599 } 594 }
595
600 return hi; 596 return hi;
601} 597}
602 598
603static u8 599static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
604ath_rc_sib_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, 600 struct ath_rate_table *rate_table,
605 struct ath_rate_table *rate_table, 601 u8 *mcs_set, u32 capflag)
606 u8 *mcs_set, u32 capflag)
607{ 602{
603 struct ath_rateset *rateset = (struct ath_rateset *)mcs_set;
604
608 u8 i, j, hi = 0; 605 u8 i, j, hi = 0;
609 606
610 /* Use intersection of working rates and valid rates */ 607 /* Use intersection of working rates and valid rates */
611 for (i = 0; i < ((struct ath_rateset *)mcs_set)->rs_nrates; i++) { 608 for (i = 0; i < rateset->rs_nrates; i++) {
612 for (j = 0; j < rate_table->rate_cnt; j++) { 609 for (j = 0; j < rate_table->rate_cnt; j++) {
613 u32 phy = rate_table->info[j].phy; 610 u32 phy = rate_table->info[j].phy;
614 u32 valid = (ath_rc_priv->single_stream ? 611 u32 valid = (ath_rc_priv->single_stream ?
615 rate_table->info[j].valid_single_stream : 612 rate_table->info[j].valid_single_stream :
616 rate_table->info[j].valid); 613 rate_table->info[j].valid);
614 u8 rate = rateset->rs_rates[i];
615 u8 dot11rate = rate_table->info[j].dot11rate;
617 616
618 if (((((struct ath_rateset *) 617 if (((rate & 0x7F) != (dot11rate & 0x7F)) ||
619 mcs_set)->rs_rates[i] & 0x7F) !=
620 (rate_table->info[j].dot11rate & 0x7F)) ||
621 !WLAN_RC_PHY_HT(phy) || 618 !WLAN_RC_PHY_HT(phy) ||
622 !WLAN_RC_PHY_HT_VALID(valid, capflag)) 619 !WLAN_RC_PHY_HT_VALID(valid, capflag))
623 continue; 620 continue;
@@ -632,26 +629,8 @@ ath_rc_sib_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
632 hi = A_MAX(hi, j); 629 hi = A_MAX(hi, j);
633 } 630 }
634 } 631 }
635 return hi;
636}
637
638u8 ath_rate_findrateix(struct ath_softc *sc,
639 u8 dot11rate)
640{
641 struct ath_rate_table *ratetable;
642 int i;
643
644 ratetable = sc->hw_rate_table[sc->sc_curmode];
645
646 if (WARN_ON(!ratetable))
647 return 0;
648
649 for (i = 0; i < ratetable->rate_cnt; i++) {
650 if ((ratetable->info[i].dot11rate & 0x7f) == (dot11rate & 0x7f))
651 return i;
652 }
653 632
654 return 0; 633 return hi;
655} 634}
656 635
657static u8 ath_rc_ratefind_ht(struct ath_softc *sc, 636static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
@@ -784,9 +763,7 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
784 763
785static void ath_rc_rate_set_series(struct ath_rate_table *rate_table , 764static void ath_rc_rate_set_series(struct ath_rate_table *rate_table ,
786 struct ieee80211_tx_rate *rate, 765 struct ieee80211_tx_rate *rate,
787 u8 tries, 766 u8 tries, u8 rix, int rtsctsenable)
788 u8 rix,
789 int rtsctsenable)
790{ 767{
791 rate->count = tries; 768 rate->count = tries;
792 rate->idx = rix; 769 rate->idx = rix;
@@ -911,15 +888,16 @@ static void ath_rc_ratefind(struct ath_softc *sc,
911 } 888 }
912} 889}
913 890
914static void ath_rc_update_ht(struct ath_softc *sc, 891static bool ath_rc_update_per(struct ath_softc *sc,
915 struct ath_rate_priv *ath_rc_priv, 892 struct ath_rate_table *rate_table,
916 struct ath_tx_info_priv *tx_info_priv, 893 struct ath_rate_priv *ath_rc_priv,
917 int tx_rate, int xretries, int retries) 894 struct ath_tx_info_priv *tx_info_priv,
895 int tx_rate, int xretries, int retries,
896 u32 now_msec)
918{ 897{
919 u32 now_msec = jiffies_to_msecs(jiffies); 898 bool state_change = false;
920 int state_change = 0, rate, count; 899 int count;
921 u8 last_per; 900 u8 last_per;
922 struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode];
923 static u32 nretry_to_per_lookup[10] = { 901 static u32 nretry_to_per_lookup[10] = {
924 100 * 0 / 1, 902 100 * 0 / 1,
925 100 * 1 / 4, 903 100 * 1 / 4,
@@ -933,24 +911,9 @@ static void ath_rc_update_ht(struct ath_softc *sc,
933 100 * 9 / 10 911 100 * 9 / 10
934 }; 912 };
935 913
936 if (!ath_rc_priv)
937 return;
938
939 ASSERT(tx_rate >= 0);
940 if (tx_rate < 0)
941 return;
942
943 /* To compensate for some imbalance between ctrl and ext. channel */
944
945 if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
946 tx_info_priv->tx.ts_rssi =
947 tx_info_priv->tx.ts_rssi < 3 ? 0 :
948 tx_info_priv->tx.ts_rssi - 3;
949
950 last_per = ath_rc_priv->state[tx_rate].per; 914 last_per = ath_rc_priv->state[tx_rate].per;
951 915
952 if (xretries) { 916 if (xretries) {
953 /* Update the PER. */
954 if (xretries == 1) { 917 if (xretries == 1) {
955 ath_rc_priv->state[tx_rate].per += 30; 918 ath_rc_priv->state[tx_rate].per += 30;
956 if (ath_rc_priv->state[tx_rate].per > 100) 919 if (ath_rc_priv->state[tx_rate].per > 100)
@@ -960,11 +923,10 @@ static void ath_rc_update_ht(struct ath_softc *sc,
960 count = ARRAY_SIZE(nretry_to_per_lookup); 923 count = ARRAY_SIZE(nretry_to_per_lookup);
961 if (retries >= count) 924 if (retries >= count)
962 retries = count - 1; 925 retries = count - 1;
926
963 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */ 927 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
964 ath_rc_priv->state[tx_rate].per = 928 ath_rc_priv->state[tx_rate].per =
965 (u8)(ath_rc_priv->state[tx_rate].per - 929 (u8)(last_per - (last_per >> 3) + (100 >> 3));
966 (ath_rc_priv->state[tx_rate].per >> 3) +
967 ((100) >> 3));
968 } 930 }
969 931
970 /* xretries == 1 or 2 */ 932 /* xretries == 1 or 2 */
@@ -972,12 +934,11 @@ static void ath_rc_update_ht(struct ath_softc *sc,
972 if (ath_rc_priv->probe_rate == tx_rate) 934 if (ath_rc_priv->probe_rate == tx_rate)
973 ath_rc_priv->probe_rate = 0; 935 ath_rc_priv->probe_rate = 0;
974 936
975 } else { /* xretries == 0 */ 937 } else { /* xretries == 0 */
976 /* Update the PER. */
977 /* Make sure it doesn't index out of array's bounds. */
978 count = ARRAY_SIZE(nretry_to_per_lookup); 938 count = ARRAY_SIZE(nretry_to_per_lookup);
979 if (retries >= count) 939 if (retries >= count)
980 retries = count - 1; 940 retries = count - 1;
941
981 if (tx_info_priv->n_bad_frames) { 942 if (tx_info_priv->n_bad_frames) {
982 /* new_PER = 7/8*old_PER + 1/8*(currentPER) 943 /* new_PER = 7/8*old_PER + 1/8*(currentPER)
983 * Assuming that n_frames is not 0. The current PER 944 * Assuming that n_frames is not 0. The current PER
@@ -991,22 +952,21 @@ static void ath_rc_update_ht(struct ath_softc *sc,
991 * the above PER. The expression below is a 952 * the above PER. The expression below is a
992 * simplified version of the sum of these two terms. 953 * simplified version of the sum of these two terms.
993 */ 954 */
994 if (tx_info_priv->n_frames > 0) 955 if (tx_info_priv->n_frames > 0) {
995 ath_rc_priv->state[tx_rate].per 956 int n_frames, n_bad_frames;
996 = (u8) 957 u8 cur_per, new_per;
997 (ath_rc_priv->state[tx_rate].per - 958
998 (ath_rc_priv->state[tx_rate].per >> 3) + 959 n_bad_frames = retries * tx_info_priv->n_frames +
999 ((100*(retries*tx_info_priv->n_frames + 960 tx_info_priv->n_bad_frames;
1000 tx_info_priv->n_bad_frames) / 961 n_frames = tx_info_priv->n_frames * (retries + 1);
1001 (tx_info_priv->n_frames * 962 cur_per = (100 * n_bad_frames / n_frames) >> 3;
1002 (retries+1))) >> 3)); 963 new_per = (u8)(last_per - (last_per >> 3) + cur_per);
964 ath_rc_priv->state[tx_rate].per = new_per;
965 }
1003 } else { 966 } else {
1004 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */ 967 ath_rc_priv->state[tx_rate].per =
1005 968 (u8)(last_per - (last_per >> 3) +
1006 ath_rc_priv->state[tx_rate].per = (u8) 969 (nretry_to_per_lookup[retries] >> 3));
1007 (ath_rc_priv->state[tx_rate].per -
1008 (ath_rc_priv->state[tx_rate].per >> 3) +
1009 (nretry_to_per_lookup[retries] >> 3));
1010 } 970 }
1011 971
1012 ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev; 972 ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev;
@@ -1018,7 +978,6 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1018 * If we got at most one retry then increase the max rate if 978 * If we got at most one retry then increase the max rate if
1019 * this was a probe. Otherwise, ignore the probe. 979 * this was a probe. Otherwise, ignore the probe.
1020 */ 980 */
1021
1022 if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) { 981 if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) {
1023 if (retries > 0 || 2 * tx_info_priv->n_bad_frames > 982 if (retries > 0 || 2 * tx_info_priv->n_bad_frames >
1024 tx_info_priv->n_frames) { 983 tx_info_priv->n_frames) {
@@ -1033,7 +992,8 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1033 } else { 992 } else {
1034 u8 probe_rate = 0; 993 u8 probe_rate = 0;
1035 994
1036 ath_rc_priv->rate_max_phy = ath_rc_priv->probe_rate; 995 ath_rc_priv->rate_max_phy =
996 ath_rc_priv->probe_rate;
1037 probe_rate = ath_rc_priv->probe_rate; 997 probe_rate = ath_rc_priv->probe_rate;
1038 998
1039 if (ath_rc_priv->state[probe_rate].per > 30) 999 if (ath_rc_priv->state[probe_rate].per > 30)
@@ -1047,8 +1007,8 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1047 * to move up faster if the probes are 1007 * to move up faster if the probes are
1048 * succesful. 1008 * succesful.
1049 */ 1009 */
1050 ath_rc_priv->probe_time = now_msec - 1010 ath_rc_priv->probe_time =
1051 rate_table->probe_interval / 2; 1011 now_msec - rate_table->probe_interval / 2;
1052 } 1012 }
1053 } 1013 }
1054 1014
@@ -1064,6 +1024,10 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1064 */ 1024 */
1065 ath_rc_priv->hw_maxretry_pktcnt = 0; 1025 ath_rc_priv->hw_maxretry_pktcnt = 0;
1066 } else { 1026 } else {
1027 int32_t rssi_ackAvg;
1028 int8_t rssi_thres;
1029 int8_t rssi_ack_vmin;
1030
1067 /* 1031 /*
1068 * It worked with no retries. First ignore bogus (small) 1032 * It worked with no retries. First ignore bogus (small)
1069 * rssi_ack values. 1033 * rssi_ack values.
@@ -1073,46 +1037,82 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1073 ath_rc_priv->hw_maxretry_pktcnt++; 1037 ath_rc_priv->hw_maxretry_pktcnt++;
1074 } 1038 }
1075 1039
1076 if (tx_info_priv->tx.ts_rssi >= 1040 if (tx_info_priv->tx.ts_rssi <
1077 rate_table->info[tx_rate].rssi_ack_validmin) { 1041 rate_table->info[tx_rate].rssi_ack_validmin)
1078 /* Average the rssi */ 1042 goto exit;
1079 if (tx_rate != ath_rc_priv->rssi_sum_rate) {
1080 ath_rc_priv->rssi_sum_rate = tx_rate;
1081 ath_rc_priv->rssi_sum =
1082 ath_rc_priv->rssi_sum_cnt = 0;
1083 }
1084 1043
1085 ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi; 1044 /* Average the rssi */
1086 ath_rc_priv->rssi_sum_cnt++; 1045 if (tx_rate != ath_rc_priv->rssi_sum_rate) {
1087 1046 ath_rc_priv->rssi_sum_rate = tx_rate;
1088 if (ath_rc_priv->rssi_sum_cnt > 4) { 1047 ath_rc_priv->rssi_sum =
1089 int32_t rssi_ackAvg = 1048 ath_rc_priv->rssi_sum_cnt = 0;
1090 (ath_rc_priv->rssi_sum + 2) / 4; 1049 }
1091 int8_t rssi_thres = 1050
1092 ath_rc_priv->state[tx_rate]. 1051 ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi;
1093 rssi_thres; 1052 ath_rc_priv->rssi_sum_cnt++;
1094 int8_t rssi_ack_vmin = 1053
1095 rate_table->info[tx_rate]. 1054 if (ath_rc_priv->rssi_sum_cnt < 4)
1096 rssi_ack_validmin; 1055 goto exit;
1097 1056
1098 ath_rc_priv->rssi_sum = 1057 rssi_ackAvg =
1099 ath_rc_priv->rssi_sum_cnt = 0; 1058 (ath_rc_priv->rssi_sum + 2) / 4;
1100 1059 rssi_thres =
1101 /* Now reduce the current 1060 ath_rc_priv->state[tx_rate].rssi_thres;
1102 * rssi threshold. */ 1061 rssi_ack_vmin =
1103 if ((rssi_ackAvg < rssi_thres + 2) && 1062 rate_table->info[tx_rate].rssi_ack_validmin;
1104 (rssi_thres > rssi_ack_vmin)) { 1063
1105 ath_rc_priv->state[tx_rate]. 1064 ath_rc_priv->rssi_sum =
1106 rssi_thres--; 1065 ath_rc_priv->rssi_sum_cnt = 0;
1107 } 1066
1108 1067 /* Now reduce the current rssi threshold */
1109 state_change = 1; 1068 if ((rssi_ackAvg < rssi_thres + 2) &&
1110 } 1069 (rssi_thres > rssi_ack_vmin)) {
1070 ath_rc_priv->state[tx_rate].rssi_thres--;
1111 } 1071 }
1072
1073 state_change = true;
1112 } 1074 }
1113 } 1075 }
1076exit:
1077 return state_change;
1078}
1079
1080/* Update PER, RSSI and whatever else that the code thinks it is doing.
1081 If you can make sense of all this, you really need to go out more. */
1114 1082
1115 /* For all cases */ 1083static void ath_rc_update_ht(struct ath_softc *sc,
1084 struct ath_rate_priv *ath_rc_priv,
1085 struct ath_tx_info_priv *tx_info_priv,
1086 int tx_rate, int xretries, int retries)
1087{
1088#define CHK_RSSI(rate) \
1089 ((ath_rc_priv->state[(rate)].rssi_thres + \
1090 rate_table->info[(rate)].rssi_ack_deltamin) > \
1091 ath_rc_priv->state[(rate)+1].rssi_thres)
1092
1093 u32 now_msec = jiffies_to_msecs(jiffies);
1094 int rate;
1095 u8 last_per;
1096 bool state_change = false;
1097 struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode];
1098 int size = ath_rc_priv->rate_table_size;
1099
1100 if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
1101 return;
1102
1103 /* To compensate for some imbalance between ctrl and ext. channel */
1104
1105 if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
1106 tx_info_priv->tx.ts_rssi =
1107 tx_info_priv->tx.ts_rssi < 3 ? 0 :
1108 tx_info_priv->tx.ts_rssi - 3;
1109
1110 last_per = ath_rc_priv->state[tx_rate].per;
1111
1112 /* Update PER first */
1113 state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
1114 tx_info_priv, tx_rate, xretries,
1115 retries, now_msec);
1116 1116
1117 /* 1117 /*
1118 * If this rate looks bad (high PER) then stop using it for 1118 * If this rate looks bad (high PER) then stop using it for
@@ -1122,7 +1122,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1122 rate_table->info[tx_rate].ratekbps <= 1122 rate_table->info[tx_rate].ratekbps <=
1123 rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) { 1123 rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
1124 ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv, 1124 ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv,
1125 (u8) tx_rate, &ath_rc_priv->rate_max_phy); 1125 (u8)tx_rate, &ath_rc_priv->rate_max_phy);
1126 1126
1127 /* Don't probe for a little while. */ 1127 /* Don't probe for a little while. */
1128 ath_rc_priv->probe_time = now_msec; 1128 ath_rc_priv->probe_time = now_msec;
@@ -1136,20 +1136,15 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1136 * made to keep the rssi thresholds monotonically 1136 * made to keep the rssi thresholds monotonically
1137 * increasing between the CCK and OFDM rates.) 1137 * increasing between the CCK and OFDM rates.)
1138 */ 1138 */
1139 for (rate = tx_rate; rate < 1139 for (rate = tx_rate; rate < size - 1; rate++) {
1140 ath_rc_priv->rate_table_size - 1; rate++) {
1141 if (rate_table->info[rate+1].phy != 1140 if (rate_table->info[rate+1].phy !=
1142 rate_table->info[tx_rate].phy) 1141 rate_table->info[tx_rate].phy)
1143 break; 1142 break;
1144 1143
1145 if (ath_rc_priv->state[rate].rssi_thres + 1144 if (CHK_RSSI(rate)) {
1146 rate_table->info[rate].rssi_ack_deltamin >
1147 ath_rc_priv->state[rate+1].rssi_thres) {
1148 ath_rc_priv->state[rate+1].rssi_thres = 1145 ath_rc_priv->state[rate+1].rssi_thres =
1149 ath_rc_priv->state[rate]. 1146 ath_rc_priv->state[rate].rssi_thres +
1150 rssi_thres + 1147 rate_table->info[rate].rssi_ack_deltamin;
1151 rate_table->info[rate].
1152 rssi_ack_deltamin;
1153 } 1148 }
1154 } 1149 }
1155 1150
@@ -1159,27 +1154,20 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1159 rate_table->info[tx_rate].phy) 1154 rate_table->info[tx_rate].phy)
1160 break; 1155 break;
1161 1156
1162 if (ath_rc_priv->state[rate].rssi_thres + 1157 if (CHK_RSSI(rate)) {
1163 rate_table->info[rate].rssi_ack_deltamin >
1164 ath_rc_priv->state[rate+1].rssi_thres) {
1165 if (ath_rc_priv->state[rate+1].rssi_thres < 1158 if (ath_rc_priv->state[rate+1].rssi_thres <
1166 rate_table->info[rate]. 1159 rate_table->info[rate].rssi_ack_deltamin)
1167 rssi_ack_deltamin)
1168 ath_rc_priv->state[rate].rssi_thres = 0; 1160 ath_rc_priv->state[rate].rssi_thres = 0;
1169 else { 1161 else {
1170 ath_rc_priv->state[rate].rssi_thres = 1162 ath_rc_priv->state[rate].rssi_thres =
1171 ath_rc_priv->state[rate+1]. 1163 ath_rc_priv->state[rate+1].rssi_thres -
1172 rssi_thres - 1164 rate_table->info[rate].rssi_ack_deltamin;
1173 rate_table->info[rate].
1174 rssi_ack_deltamin;
1175 } 1165 }
1176 1166
1177 if (ath_rc_priv->state[rate].rssi_thres < 1167 if (ath_rc_priv->state[rate].rssi_thres <
1178 rate_table->info[rate]. 1168 rate_table->info[rate].rssi_ack_validmin) {
1179 rssi_ack_validmin) {
1180 ath_rc_priv->state[rate].rssi_thres = 1169 ath_rc_priv->state[rate].rssi_thres =
1181 rate_table->info[rate]. 1170 rate_table->info[rate].rssi_ack_validmin;
1182 rssi_ack_validmin;
1183 } 1171 }
1184 } 1172 }
1185 } 1173 }
@@ -1202,8 +1190,9 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1202 } 1190 }
1203 1191
1204 /* Maintain monotonicity for rates above the current rate */ 1192 /* Maintain monotonicity for rates above the current rate */
1205 for (rate = tx_rate; rate < ath_rc_priv->rate_table_size - 1; rate++) { 1193 for (rate = tx_rate; rate < size - 1; rate++) {
1206 if (ath_rc_priv->state[rate+1].per < ath_rc_priv->state[rate].per) 1194 if (ath_rc_priv->state[rate+1].per <
1195 ath_rc_priv->state[rate].per)
1207 ath_rc_priv->state[rate+1].per = 1196 ath_rc_priv->state[rate+1].per =
1208 ath_rc_priv->state[rate].per; 1197 ath_rc_priv->state[rate].per;
1209 } 1198 }
@@ -1213,7 +1202,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1213 if (now_msec - ath_rc_priv->rssi_down_time >= 1202 if (now_msec - ath_rc_priv->rssi_down_time >=
1214 rate_table->rssi_reduce_interval) { 1203 rate_table->rssi_reduce_interval) {
1215 1204
1216 for (rate = 0; rate < ath_rc_priv->rate_table_size; rate++) { 1205 for (rate = 0; rate < size; rate++) {
1217 if (ath_rc_priv->state[rate].rssi_thres > 1206 if (ath_rc_priv->state[rate].rssi_thres >
1218 rate_table->info[rate].rssi_ack_validmin) 1207 rate_table->info[rate].rssi_ack_validmin)
1219 ath_rc_priv->state[rate].rssi_thres -= 1; 1208 ath_rc_priv->state[rate].rssi_thres -= 1;
@@ -1225,13 +1214,33 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1225 * and PER (different for CCK and OFDM). */ 1214 * and PER (different for CCK and OFDM). */
1226 if (now_msec - ath_rc_priv->per_down_time >= 1215 if (now_msec - ath_rc_priv->per_down_time >=
1227 rate_table->rssi_reduce_interval) { 1216 rate_table->rssi_reduce_interval) {
1228 for (rate = 0; rate < ath_rc_priv->rate_table_size; rate++) { 1217 for (rate = 0; rate < size; rate++) {
1229 ath_rc_priv->state[rate].per = 1218 ath_rc_priv->state[rate].per =
1230 7 * ath_rc_priv->state[rate].per / 8; 1219 7 * ath_rc_priv->state[rate].per / 8;
1231 } 1220 }
1232 1221
1233 ath_rc_priv->per_down_time = now_msec; 1222 ath_rc_priv->per_down_time = now_msec;
1234 } 1223 }
1224
1225#undef CHK_RSSI
1226}
1227
1228static int ath_rc_get_rateindex(struct ath_rate_table *rate_table,
1229 struct ieee80211_tx_rate *rate)
1230{
1231 int rix;
1232
1233 if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
1234 (rate->flags & IEEE80211_TX_RC_SHORT_GI))
1235 rix = rate_table->info[rate->idx].ht_index;
1236 else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
1237 rix = rate_table->info[rate->idx].sgi_index;
1238 else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1239 rix = rate_table->info[rate->idx].cw40index;
1240 else
1241 rix = rate_table->info[rate->idx].base_index;
1242
1243 return rix;
1235} 1244}
1236 1245
1237static void ath_rc_tx_status(struct ath_softc *sc, 1246static void ath_rc_tx_status(struct ath_softc *sc,
@@ -1243,7 +1252,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
1243 struct ath_rate_table *rate_table; 1252 struct ath_rate_table *rate_table;
1244 struct ieee80211_tx_rate *rates = tx_info->status.rates; 1253 struct ieee80211_tx_rate *rates = tx_info->status.rates;
1245 u8 flags; 1254 u8 flags;
1246 u32 series = 0, rix; 1255 u32 i = 0, rix;
1247 1256
1248 rate_table = sc->hw_rate_table[sc->sc_curmode]; 1257 rate_table = sc->hw_rate_table[sc->sc_curmode];
1249 1258
@@ -1253,32 +1262,22 @@ static void ath_rc_tx_status(struct ath_softc *sc,
1253 */ 1262 */
1254 if (final_ts_idx != 0) { 1263 if (final_ts_idx != 0) {
1255 /* Process intermediate rates that failed.*/ 1264 /* Process intermediate rates that failed.*/
1256 for (series = 0; series < final_ts_idx ; series++) { 1265 for (i = 0; i < final_ts_idx ; i++) {
1257 if (rates[series].count != 0 && (rates[series].idx >= 0)) { 1266 if (rates[i].count != 0 && (rates[i].idx >= 0)) {
1258 flags = rates[series].flags; 1267 flags = rates[i].flags;
1268
1259 /* If HT40 and we have switched mode from 1269 /* If HT40 and we have switched mode from
1260 * 40 to 20 => don't update */ 1270 * 40 to 20 => don't update */
1271
1261 if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && 1272 if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
1262 (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) 1273 (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG))
1263 return; 1274 return;
1264 1275
1265 if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && 1276 rix = ath_rc_get_rateindex(rate_table, &rates[i]);
1266 (flags & IEEE80211_TX_RC_SHORT_GI))
1267 rix = rate_table->info[
1268 rates[series].idx].ht_index;
1269 else if (flags & IEEE80211_TX_RC_SHORT_GI)
1270 rix = rate_table->info[
1271 rates[series].idx].sgi_index;
1272 else if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1273 rix = rate_table->info[
1274 rates[series].idx].cw40index;
1275 else
1276 rix = rate_table->info[
1277 rates[series].idx].base_index;
1278 ath_rc_update_ht(sc, ath_rc_priv, 1277 ath_rc_update_ht(sc, ath_rc_priv,
1279 tx_info_priv, rix, 1278 tx_info_priv, rix,
1280 xretries ? 1 : 2, 1279 xretries ? 1 : 2,
1281 rates[series].count); 1280 rates[i].count);
1282 } 1281 }
1283 } 1282 }
1284 } else { 1283 } else {
@@ -1292,24 +1291,17 @@ static void ath_rc_tx_status(struct ath_softc *sc,
1292 xretries = 2; 1291 xretries = 2;
1293 } 1292 }
1294 1293
1295 flags = rates[series].flags; 1294 flags = rates[i].flags;
1295
1296 /* If HT40 and we have switched mode from 40 to 20 => don't update */ 1296 /* If HT40 and we have switched mode from 40 to 20 => don't update */
1297 if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && 1297 if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
1298 (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) { 1298 (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) {
1299 return; 1299 return;
1300 } 1300 }
1301 1301
1302 if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && (flags & IEEE80211_TX_RC_SHORT_GI)) 1302 rix = ath_rc_get_rateindex(rate_table, &rates[i]);
1303 rix = rate_table->info[rates[series].idx].ht_index;
1304 else if (flags & IEEE80211_TX_RC_SHORT_GI)
1305 rix = rate_table->info[rates[series].idx].sgi_index;
1306 else if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
1307 rix = rate_table->info[rates[series].idx].cw40index;
1308 else
1309 rix = rate_table->info[rates[series].idx].base_index;
1310
1311 ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix, 1303 ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix,
1312 xretries, long_retry); 1304 xretries, long_retry);
1313} 1305}
1314 1306
1315static void ath_rc_init(struct ath_softc *sc, 1307static void ath_rc_init(struct ath_softc *sc,
@@ -1362,14 +1354,14 @@ static void ath_rc_init(struct ath_softc *sc,
1362 1354
1363 if (!rateset->rs_nrates) { 1355 if (!rateset->rs_nrates) {
1364 /* No working rate, just initialize valid rates */ 1356 /* No working rate, just initialize valid rates */
1365 hi = ath_rc_sib_init_validrates(ath_rc_priv, rate_table, 1357 hi = ath_rc_init_validrates(ath_rc_priv, rate_table,
1366 ath_rc_priv->ht_cap); 1358 ath_rc_priv->ht_cap);
1367 } else { 1359 } else {
1368 /* Use intersection of working rates and valid rates */ 1360 /* Use intersection of working rates and valid rates */
1369 hi = ath_rc_sib_setvalid_rates(ath_rc_priv, rate_table, 1361 hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table,
1370 rateset, ath_rc_priv->ht_cap); 1362 rateset, ath_rc_priv->ht_cap);
1371 if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) { 1363 if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
1372 hthi = ath_rc_sib_setvalid_htrates(ath_rc_priv, 1364 hthi = ath_rc_setvalid_htrates(ath_rc_priv,
1373 rate_table, 1365 rate_table,
1374 ht_mcs, 1366 ht_mcs,
1375 ath_rc_priv->ht_cap); 1367 ath_rc_priv->ht_cap);
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h
index dff4b7ade3df..297dff96c3a1 100644
--- a/drivers/net/wireless/ath9k/rc.h
+++ b/drivers/net/wireless/ath9k/rc.h
@@ -27,6 +27,11 @@ struct ath_softc;
27#define RATE_TABLE_SIZE 64 27#define RATE_TABLE_SIZE 64
28#define MAX_TX_RATE_PHY 48 28#define MAX_TX_RATE_PHY 48
29 29
30/* VALID_ALL - valid for 20/40/Legacy,
31 * VALID - Legacy only,
32 * VALID_20 - HT 20 only,
33 * VALID_40 - HT 40 only */
34
30#define INVALID 0x0 35#define INVALID 0x0
31#define VALID 0x1 36#define VALID 0x1
32#define VALID_20 0x2 37#define VALID_20 0x2