diff options
author | Sujith <Sujith.Manoharan@atheros.com> | 2008-11-17 22:38:33 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-11-26 09:47:32 -0500 |
commit | 2c5a744d43a6a08666930906742fbe704739ba6f (patch) | |
tree | a1de6a3535f62b26dc0104f451dd3ed87ab4dd08 /drivers/net/wireless/ath9k/rc.c | |
parent | 46d14a58ffb42702e4c1b8bb88cfa05414617f4c (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/rc.c')
-rw-r--r-- | drivers/net/wireless/ath9k/rc.c | 386 |
1 files changed, 189 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 | ||
474 | static inline int | 469 | static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table, |
475 | ath_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 | ||
528 | static u8 | 524 | static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv, |
529 | ath_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 | ||
558 | static u8 | 554 | static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv, |
559 | ath_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 | ||
603 | static u8 | 599 | static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, |
604 | ath_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 | |||
638 | u8 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 | ||
657 | static u8 ath_rc_ratefind_ht(struct ath_softc *sc, | 636 | static 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 | ||
785 | static void ath_rc_rate_set_series(struct ath_rate_table *rate_table , | 764 | static 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 | ||
914 | static void ath_rc_update_ht(struct ath_softc *sc, | 891 | static 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 | } |
1076 | exit: | ||
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 */ | 1083 | static 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 | |||
1228 | static 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 | ||
1237 | static void ath_rc_tx_status(struct ath_softc *sc, | 1246 | static 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 | ||
1315 | static void ath_rc_init(struct ath_softc *sc, | 1307 | static 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); |