18da07830SSujith Manoharan /*
28da07830SSujith Manoharan * Copyright (c) 2012 Qualcomm Atheros, Inc.
38da07830SSujith Manoharan *
48da07830SSujith Manoharan * Permission to use, copy, modify, and/or distribute this software for any
58da07830SSujith Manoharan * purpose with or without fee is hereby granted, provided that the above
68da07830SSujith Manoharan * copyright notice and this permission notice appear in all copies.
78da07830SSujith Manoharan *
88da07830SSujith Manoharan * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
98da07830SSujith Manoharan * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
108da07830SSujith Manoharan * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
118da07830SSujith Manoharan * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
128da07830SSujith Manoharan * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
138da07830SSujith Manoharan * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
148da07830SSujith Manoharan * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
158da07830SSujith Manoharan */
168da07830SSujith Manoharan
178da07830SSujith Manoharan #include "ath9k.h"
188da07830SSujith Manoharan
19fd7f8387SSujith Manoharan /*
20fd7f8387SSujith Manoharan * AR9285
21fd7f8387SSujith Manoharan * ======
22fd7f8387SSujith Manoharan *
23fd7f8387SSujith Manoharan * EEPROM has 2 4-bit fields containing the card configuration.
24fd7f8387SSujith Manoharan *
25fd7f8387SSujith Manoharan * antdiv_ctl1:
26fd7f8387SSujith Manoharan * ------------
27fd7f8387SSujith Manoharan * bb_enable_ant_div_lnadiv : 1
28fd7f8387SSujith Manoharan * bb_ant_div_alt_gaintb : 1
29fd7f8387SSujith Manoharan * bb_ant_div_main_gaintb : 1
30fd7f8387SSujith Manoharan * bb_enable_ant_fast_div : 1
31fd7f8387SSujith Manoharan *
32fd7f8387SSujith Manoharan * antdiv_ctl2:
33fd7f8387SSujith Manoharan * -----------
34fd7f8387SSujith Manoharan * bb_ant_div_alt_lnaconf : 2
35fd7f8387SSujith Manoharan * bb_ant_div_main_lnaconf : 2
36fd7f8387SSujith Manoharan *
37fd7f8387SSujith Manoharan * The EEPROM bits are used as follows:
38fd7f8387SSujith Manoharan * ------------------------------------
39fd7f8387SSujith Manoharan *
40fd7f8387SSujith Manoharan * bb_enable_ant_div_lnadiv - Enable LNA path rx antenna diversity/combining.
41fd7f8387SSujith Manoharan * Set in AR_PHY_MULTICHAIN_GAIN_CTL.
42fd7f8387SSujith Manoharan *
43fd7f8387SSujith Manoharan * bb_ant_div_[alt/main]_gaintb - 0 -> Antenna config Alt/Main uses gaintable 0
44fd7f8387SSujith Manoharan * 1 -> Antenna config Alt/Main uses gaintable 1
45fd7f8387SSujith Manoharan * Set in AR_PHY_MULTICHAIN_GAIN_CTL.
46fd7f8387SSujith Manoharan *
47fd7f8387SSujith Manoharan * bb_enable_ant_fast_div - Enable fast antenna diversity.
48fd7f8387SSujith Manoharan * Set in AR_PHY_CCK_DETECT.
49fd7f8387SSujith Manoharan *
50fd7f8387SSujith Manoharan * bb_ant_div_[alt/main]_lnaconf - Alt/Main LNA diversity/combining input config.
51fd7f8387SSujith Manoharan * Set in AR_PHY_MULTICHAIN_GAIN_CTL.
52fd7f8387SSujith Manoharan * 10=LNA1
53fd7f8387SSujith Manoharan * 01=LNA2
54fd7f8387SSujith Manoharan * 11=LNA1+LNA2
55fd7f8387SSujith Manoharan * 00=LNA1-LNA2
56fd7f8387SSujith Manoharan *
57fd7f8387SSujith Manoharan * AR9485 / AR9565 / AR9331
58fd7f8387SSujith Manoharan * ========================
59fd7f8387SSujith Manoharan *
60fd7f8387SSujith Manoharan * The same bits are present in the EEPROM, but the location in the
61fd7f8387SSujith Manoharan * EEPROM is different (ant_div_control in ar9300_BaseExtension_1).
62fd7f8387SSujith Manoharan *
63fd7f8387SSujith Manoharan * ant_div_alt_lnaconf ==> bit 0~1
64fd7f8387SSujith Manoharan * ant_div_main_lnaconf ==> bit 2~3
65fd7f8387SSujith Manoharan * ant_div_alt_gaintb ==> bit 4
66fd7f8387SSujith Manoharan * ant_div_main_gaintb ==> bit 5
67fd7f8387SSujith Manoharan * enable_ant_div_lnadiv ==> bit 6
68fd7f8387SSujith Manoharan * enable_ant_fast_div ==> bit 7
69fd7f8387SSujith Manoharan */
70fd7f8387SSujith Manoharan
ath_is_alt_ant_ratio_better(struct ath_ant_comb * antcomb,int alt_ratio,int maxdelta,int mindelta,int main_rssi_avg,int alt_rssi_avg,int pkt_count)713afa6b4fSSujith Manoharan static inline bool ath_is_alt_ant_ratio_better(struct ath_ant_comb *antcomb,
723afa6b4fSSujith Manoharan int alt_ratio, int maxdelta,
738da07830SSujith Manoharan int mindelta, int main_rssi_avg,
748da07830SSujith Manoharan int alt_rssi_avg, int pkt_count)
758da07830SSujith Manoharan {
763afa6b4fSSujith Manoharan if (pkt_count <= 50)
773afa6b4fSSujith Manoharan return false;
783afa6b4fSSujith Manoharan
793afa6b4fSSujith Manoharan if (alt_rssi_avg > main_rssi_avg + mindelta)
803afa6b4fSSujith Manoharan return true;
813afa6b4fSSujith Manoharan
823afa6b4fSSujith Manoharan if (alt_ratio >= antcomb->ant_ratio2 &&
833afa6b4fSSujith Manoharan alt_rssi_avg >= antcomb->low_rssi_thresh &&
843afa6b4fSSujith Manoharan (alt_rssi_avg > main_rssi_avg + maxdelta))
853afa6b4fSSujith Manoharan return true;
863afa6b4fSSujith Manoharan
873afa6b4fSSujith Manoharan return false;
888da07830SSujith Manoharan }
898da07830SSujith Manoharan
ath_ant_div_comb_alt_check(struct ath_hw_antcomb_conf * conf,struct ath_ant_comb * antcomb,int alt_ratio,int alt_rssi_avg,int main_rssi_avg)90ef999114SSujith Manoharan static inline bool ath_ant_div_comb_alt_check(struct ath_hw_antcomb_conf *conf,
913afa6b4fSSujith Manoharan struct ath_ant_comb *antcomb,
92552bde40SSujith Manoharan int alt_ratio, int alt_rssi_avg,
93552bde40SSujith Manoharan int main_rssi_avg)
948da07830SSujith Manoharan {
95552bde40SSujith Manoharan bool result, set1, set2;
96552bde40SSujith Manoharan
97552bde40SSujith Manoharan result = set1 = set2 = false;
98552bde40SSujith Manoharan
99ef999114SSujith Manoharan if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2 &&
100ef999114SSujith Manoharan conf->alt_lna_conf == ATH_ANT_DIV_COMB_LNA1)
101552bde40SSujith Manoharan set1 = true;
102552bde40SSujith Manoharan
103ef999114SSujith Manoharan if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA1 &&
104ef999114SSujith Manoharan conf->alt_lna_conf == ATH_ANT_DIV_COMB_LNA2)
105552bde40SSujith Manoharan set2 = true;
106552bde40SSujith Manoharan
107ef999114SSujith Manoharan switch (conf->div_group) {
1088da07830SSujith Manoharan case 0:
1098da07830SSujith Manoharan if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
1108da07830SSujith Manoharan result = true;
1118da07830SSujith Manoharan break;
1128da07830SSujith Manoharan case 1:
1138da07830SSujith Manoharan case 2:
1143afa6b4fSSujith Manoharan if (alt_rssi_avg < 4 || alt_rssi_avg < antcomb->low_rssi_thresh)
115552bde40SSujith Manoharan break;
116552bde40SSujith Manoharan
117552bde40SSujith Manoharan if ((set1 && (alt_rssi_avg >= (main_rssi_avg - 5))) ||
1183afa6b4fSSujith Manoharan (set2 && (alt_rssi_avg >= (main_rssi_avg - 2))) ||
1193afa6b4fSSujith Manoharan (alt_ratio > antcomb->ant_ratio))
1208da07830SSujith Manoharan result = true;
121552bde40SSujith Manoharan
122552bde40SSujith Manoharan break;
123552bde40SSujith Manoharan case 3:
1243afa6b4fSSujith Manoharan if (alt_rssi_avg < 4 || alt_rssi_avg < antcomb->low_rssi_thresh)
125552bde40SSujith Manoharan break;
126552bde40SSujith Manoharan
127552bde40SSujith Manoharan if ((set1 && (alt_rssi_avg >= (main_rssi_avg - 3))) ||
1283afa6b4fSSujith Manoharan (set2 && (alt_rssi_avg >= (main_rssi_avg + 3))) ||
1293afa6b4fSSujith Manoharan (alt_ratio > antcomb->ant_ratio))
130552bde40SSujith Manoharan result = true;
131552bde40SSujith Manoharan
1328da07830SSujith Manoharan break;
1338da07830SSujith Manoharan }
1348da07830SSujith Manoharan
1358da07830SSujith Manoharan return result;
1368da07830SSujith Manoharan }
1378da07830SSujith Manoharan
ath_lnaconf_alt_good_scan(struct ath_ant_comb * antcomb,struct ath_hw_antcomb_conf ant_conf,int main_rssi_avg)1388da07830SSujith Manoharan static void ath_lnaconf_alt_good_scan(struct ath_ant_comb *antcomb,
1398da07830SSujith Manoharan struct ath_hw_antcomb_conf ant_conf,
1408da07830SSujith Manoharan int main_rssi_avg)
1418da07830SSujith Manoharan {
1428da07830SSujith Manoharan antcomb->quick_scan_cnt = 0;
1438da07830SSujith Manoharan
1448da07830SSujith Manoharan if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
1458da07830SSujith Manoharan antcomb->rssi_lna2 = main_rssi_avg;
1468da07830SSujith Manoharan else if (ant_conf.main_lna_conf == ATH_ANT_DIV_COMB_LNA1)
1478da07830SSujith Manoharan antcomb->rssi_lna1 = main_rssi_avg;
1488da07830SSujith Manoharan
1498da07830SSujith Manoharan switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) {
1508da07830SSujith Manoharan case 0x10: /* LNA2 A-B */
1518da07830SSujith Manoharan antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
1528da07830SSujith Manoharan antcomb->first_quick_scan_conf =
1538da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
1548da07830SSujith Manoharan antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1;
1558da07830SSujith Manoharan break;
1568da07830SSujith Manoharan case 0x20: /* LNA1 A-B */
1578da07830SSujith Manoharan antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
1588da07830SSujith Manoharan antcomb->first_quick_scan_conf =
1598da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
1608da07830SSujith Manoharan antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2;
1618da07830SSujith Manoharan break;
1628da07830SSujith Manoharan case 0x21: /* LNA1 LNA2 */
1638da07830SSujith Manoharan antcomb->main_conf = ATH_ANT_DIV_COMB_LNA2;
1648da07830SSujith Manoharan antcomb->first_quick_scan_conf =
1658da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
1668da07830SSujith Manoharan antcomb->second_quick_scan_conf =
1678da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
1688da07830SSujith Manoharan break;
1698da07830SSujith Manoharan case 0x12: /* LNA2 LNA1 */
1708da07830SSujith Manoharan antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1;
1718da07830SSujith Manoharan antcomb->first_quick_scan_conf =
1728da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
1738da07830SSujith Manoharan antcomb->second_quick_scan_conf =
1748da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
1758da07830SSujith Manoharan break;
1768da07830SSujith Manoharan case 0x13: /* LNA2 A+B */
1778da07830SSujith Manoharan antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
1788da07830SSujith Manoharan antcomb->first_quick_scan_conf =
1798da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
1808da07830SSujith Manoharan antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA1;
1818da07830SSujith Manoharan break;
1828da07830SSujith Manoharan case 0x23: /* LNA1 A+B */
1838da07830SSujith Manoharan antcomb->main_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
1848da07830SSujith Manoharan antcomb->first_quick_scan_conf =
1858da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
1868da07830SSujith Manoharan antcomb->second_quick_scan_conf = ATH_ANT_DIV_COMB_LNA2;
1878da07830SSujith Manoharan break;
1888da07830SSujith Manoharan default:
1898da07830SSujith Manoharan break;
1908da07830SSujith Manoharan }
1918da07830SSujith Manoharan }
1928da07830SSujith Manoharan
ath_ant_set_alt_ratio(struct ath_ant_comb * antcomb,struct ath_hw_antcomb_conf * conf)19337133002SSujith Manoharan static void ath_ant_set_alt_ratio(struct ath_ant_comb *antcomb,
19437133002SSujith Manoharan struct ath_hw_antcomb_conf *conf)
19537133002SSujith Manoharan {
19637133002SSujith Manoharan /* set alt to the conf with maximun ratio */
19737133002SSujith Manoharan if (antcomb->first_ratio && antcomb->second_ratio) {
19837133002SSujith Manoharan if (antcomb->rssi_second > antcomb->rssi_third) {
19937133002SSujith Manoharan /* first alt*/
20037133002SSujith Manoharan if ((antcomb->first_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) ||
20137133002SSujith Manoharan (antcomb->first_quick_scan_conf == ATH_ANT_DIV_COMB_LNA2))
20237133002SSujith Manoharan /* Set alt LNA1 or LNA2*/
20337133002SSujith Manoharan if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
20437133002SSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
20537133002SSujith Manoharan else
20637133002SSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
20737133002SSujith Manoharan else
20837133002SSujith Manoharan /* Set alt to A+B or A-B */
20937133002SSujith Manoharan conf->alt_lna_conf =
21037133002SSujith Manoharan antcomb->first_quick_scan_conf;
21137133002SSujith Manoharan } else if ((antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) ||
21237133002SSujith Manoharan (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA2)) {
21337133002SSujith Manoharan /* Set alt LNA1 or LNA2 */
21437133002SSujith Manoharan if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
21537133002SSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
21637133002SSujith Manoharan else
21737133002SSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
21837133002SSujith Manoharan } else {
21937133002SSujith Manoharan /* Set alt to A+B or A-B */
22037133002SSujith Manoharan conf->alt_lna_conf = antcomb->second_quick_scan_conf;
22137133002SSujith Manoharan }
22237133002SSujith Manoharan } else if (antcomb->first_ratio) {
22337133002SSujith Manoharan /* first alt */
22437133002SSujith Manoharan if ((antcomb->first_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) ||
22537133002SSujith Manoharan (antcomb->first_quick_scan_conf == ATH_ANT_DIV_COMB_LNA2))
22637133002SSujith Manoharan /* Set alt LNA1 or LNA2 */
22737133002SSujith Manoharan if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
22837133002SSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
22937133002SSujith Manoharan else
23037133002SSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
23137133002SSujith Manoharan else
23237133002SSujith Manoharan /* Set alt to A+B or A-B */
23337133002SSujith Manoharan conf->alt_lna_conf = antcomb->first_quick_scan_conf;
23437133002SSujith Manoharan } else if (antcomb->second_ratio) {
23537133002SSujith Manoharan /* second alt */
23637133002SSujith Manoharan if ((antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA1) ||
23737133002SSujith Manoharan (antcomb->second_quick_scan_conf == ATH_ANT_DIV_COMB_LNA2))
23837133002SSujith Manoharan /* Set alt LNA1 or LNA2 */
23937133002SSujith Manoharan if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
24037133002SSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
24137133002SSujith Manoharan else
24237133002SSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
24337133002SSujith Manoharan else
24437133002SSujith Manoharan /* Set alt to A+B or A-B */
24537133002SSujith Manoharan conf->alt_lna_conf = antcomb->second_quick_scan_conf;
24637133002SSujith Manoharan } else {
24737133002SSujith Manoharan /* main is largest */
24837133002SSujith Manoharan if ((antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) ||
24937133002SSujith Manoharan (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2))
25037133002SSujith Manoharan /* Set alt LNA1 or LNA2 */
25137133002SSujith Manoharan if (conf->main_lna_conf == ATH_ANT_DIV_COMB_LNA2)
25237133002SSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
25337133002SSujith Manoharan else
25437133002SSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
25537133002SSujith Manoharan else
25637133002SSujith Manoharan /* Set alt to A+B or A-B */
25737133002SSujith Manoharan conf->alt_lna_conf = antcomb->main_conf;
25837133002SSujith Manoharan }
25937133002SSujith Manoharan }
26037133002SSujith Manoharan
ath_select_ant_div_from_quick_scan(struct ath_ant_comb * antcomb,struct ath_hw_antcomb_conf * div_ant_conf,int main_rssi_avg,int alt_rssi_avg,int alt_ratio)2618da07830SSujith Manoharan static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
2628da07830SSujith Manoharan struct ath_hw_antcomb_conf *div_ant_conf,
2638da07830SSujith Manoharan int main_rssi_avg, int alt_rssi_avg,
2648da07830SSujith Manoharan int alt_ratio)
2658da07830SSujith Manoharan {
2668da07830SSujith Manoharan /* alt_good */
2678da07830SSujith Manoharan switch (antcomb->quick_scan_cnt) {
2688da07830SSujith Manoharan case 0:
2698da07830SSujith Manoharan /* set alt to main, and alt to first conf */
2708da07830SSujith Manoharan div_ant_conf->main_lna_conf = antcomb->main_conf;
2718da07830SSujith Manoharan div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf;
2728da07830SSujith Manoharan break;
2738da07830SSujith Manoharan case 1:
2748da07830SSujith Manoharan /* set alt to main, and alt to first conf */
2758da07830SSujith Manoharan div_ant_conf->main_lna_conf = antcomb->main_conf;
2768da07830SSujith Manoharan div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf;
2778da07830SSujith Manoharan antcomb->rssi_first = main_rssi_avg;
2788da07830SSujith Manoharan antcomb->rssi_second = alt_rssi_avg;
2798da07830SSujith Manoharan
2808da07830SSujith Manoharan if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) {
2818da07830SSujith Manoharan /* main is LNA1 */
2823afa6b4fSSujith Manoharan if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
2838da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
2848da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
2858da07830SSujith Manoharan main_rssi_avg, alt_rssi_avg,
2868da07830SSujith Manoharan antcomb->total_pkt_count))
2878da07830SSujith Manoharan antcomb->first_ratio = true;
2888da07830SSujith Manoharan else
2898da07830SSujith Manoharan antcomb->first_ratio = false;
2908da07830SSujith Manoharan } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) {
2913afa6b4fSSujith Manoharan if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
2928da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
2938da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
2948da07830SSujith Manoharan main_rssi_avg, alt_rssi_avg,
2958da07830SSujith Manoharan antcomb->total_pkt_count))
2968da07830SSujith Manoharan antcomb->first_ratio = true;
2978da07830SSujith Manoharan else
2988da07830SSujith Manoharan antcomb->first_ratio = false;
2998da07830SSujith Manoharan } else {
3003afa6b4fSSujith Manoharan if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
3019ddf0301SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
3029ddf0301SSujith Manoharan 0,
3039ddf0301SSujith Manoharan main_rssi_avg, alt_rssi_avg,
3049ddf0301SSujith Manoharan antcomb->total_pkt_count))
3058da07830SSujith Manoharan antcomb->first_ratio = true;
3068da07830SSujith Manoharan else
3078da07830SSujith Manoharan antcomb->first_ratio = false;
3088da07830SSujith Manoharan }
3098da07830SSujith Manoharan break;
3108da07830SSujith Manoharan case 2:
3118da07830SSujith Manoharan antcomb->alt_good = false;
3128da07830SSujith Manoharan antcomb->scan_not_start = false;
3138da07830SSujith Manoharan antcomb->scan = false;
3148da07830SSujith Manoharan antcomb->rssi_first = main_rssi_avg;
3158da07830SSujith Manoharan antcomb->rssi_third = alt_rssi_avg;
3168da07830SSujith Manoharan
31737133002SSujith Manoharan switch(antcomb->second_quick_scan_conf) {
31837133002SSujith Manoharan case ATH_ANT_DIV_COMB_LNA1:
3198da07830SSujith Manoharan antcomb->rssi_lna1 = alt_rssi_avg;
32037133002SSujith Manoharan break;
32137133002SSujith Manoharan case ATH_ANT_DIV_COMB_LNA2:
3228da07830SSujith Manoharan antcomb->rssi_lna2 = alt_rssi_avg;
32337133002SSujith Manoharan break;
32437133002SSujith Manoharan case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2:
3258da07830SSujith Manoharan if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2)
3268da07830SSujith Manoharan antcomb->rssi_lna2 = main_rssi_avg;
3278da07830SSujith Manoharan else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1)
3288da07830SSujith Manoharan antcomb->rssi_lna1 = main_rssi_avg;
32937133002SSujith Manoharan break;
33037133002SSujith Manoharan default:
33137133002SSujith Manoharan break;
3328da07830SSujith Manoharan }
3338da07830SSujith Manoharan
3348da07830SSujith Manoharan if (antcomb->rssi_lna2 > antcomb->rssi_lna1 +
335f96bd2adSSujith Manoharan div_ant_conf->lna1_lna2_switch_delta)
3368da07830SSujith Manoharan div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
3378da07830SSujith Manoharan else
3388da07830SSujith Manoharan div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
3398da07830SSujith Manoharan
3408da07830SSujith Manoharan if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) {
3413afa6b4fSSujith Manoharan if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
3428da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
3438da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
3448da07830SSujith Manoharan main_rssi_avg, alt_rssi_avg,
3458da07830SSujith Manoharan antcomb->total_pkt_count))
3468da07830SSujith Manoharan antcomb->second_ratio = true;
3478da07830SSujith Manoharan else
3488da07830SSujith Manoharan antcomb->second_ratio = false;
3498da07830SSujith Manoharan } else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) {
3503afa6b4fSSujith Manoharan if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
3518da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
3528da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
3538da07830SSujith Manoharan main_rssi_avg, alt_rssi_avg,
3548da07830SSujith Manoharan antcomb->total_pkt_count))
3558da07830SSujith Manoharan antcomb->second_ratio = true;
3568da07830SSujith Manoharan else
3578da07830SSujith Manoharan antcomb->second_ratio = false;
3588da07830SSujith Manoharan } else {
3593afa6b4fSSujith Manoharan if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
3609ddf0301SSujith Manoharan ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
3619ddf0301SSujith Manoharan 0,
3629ddf0301SSujith Manoharan main_rssi_avg, alt_rssi_avg,
3639ddf0301SSujith Manoharan antcomb->total_pkt_count))
3648da07830SSujith Manoharan antcomb->second_ratio = true;
3658da07830SSujith Manoharan else
3668da07830SSujith Manoharan antcomb->second_ratio = false;
3678da07830SSujith Manoharan }
3688da07830SSujith Manoharan
36937133002SSujith Manoharan ath_ant_set_alt_ratio(antcomb, div_ant_conf);
37037133002SSujith Manoharan
3718da07830SSujith Manoharan break;
3728da07830SSujith Manoharan default:
3738da07830SSujith Manoharan break;
3748da07830SSujith Manoharan }
3758da07830SSujith Manoharan }
3768da07830SSujith Manoharan
ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf * ant_conf,struct ath_ant_comb * antcomb,int alt_ratio)3778da07830SSujith Manoharan static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
3788da07830SSujith Manoharan struct ath_ant_comb *antcomb,
3798da07830SSujith Manoharan int alt_ratio)
3808da07830SSujith Manoharan {
381d85ed419SSujith Manoharan ant_conf->main_gaintb = 0;
382d85ed419SSujith Manoharan ant_conf->alt_gaintb = 0;
383d85ed419SSujith Manoharan
3848da07830SSujith Manoharan if (ant_conf->div_group == 0) {
3858da07830SSujith Manoharan /* Adjust the fast_div_bias based on main and alt lna conf */
3868da07830SSujith Manoharan switch ((ant_conf->main_lna_conf << 4) |
3878da07830SSujith Manoharan ant_conf->alt_lna_conf) {
3888da07830SSujith Manoharan case 0x01: /* A-B LNA2 */
3898da07830SSujith Manoharan ant_conf->fast_div_bias = 0x3b;
3908da07830SSujith Manoharan break;
3918da07830SSujith Manoharan case 0x02: /* A-B LNA1 */
3928da07830SSujith Manoharan ant_conf->fast_div_bias = 0x3d;
3938da07830SSujith Manoharan break;
3948da07830SSujith Manoharan case 0x03: /* A-B A+B */
3958da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
3968da07830SSujith Manoharan break;
3978da07830SSujith Manoharan case 0x10: /* LNA2 A-B */
3988da07830SSujith Manoharan ant_conf->fast_div_bias = 0x7;
3998da07830SSujith Manoharan break;
4008da07830SSujith Manoharan case 0x12: /* LNA2 LNA1 */
4018da07830SSujith Manoharan ant_conf->fast_div_bias = 0x2;
4028da07830SSujith Manoharan break;
4038da07830SSujith Manoharan case 0x13: /* LNA2 A+B */
4048da07830SSujith Manoharan ant_conf->fast_div_bias = 0x7;
4058da07830SSujith Manoharan break;
4068da07830SSujith Manoharan case 0x20: /* LNA1 A-B */
4078da07830SSujith Manoharan ant_conf->fast_div_bias = 0x6;
4088da07830SSujith Manoharan break;
4098da07830SSujith Manoharan case 0x21: /* LNA1 LNA2 */
4108da07830SSujith Manoharan ant_conf->fast_div_bias = 0x0;
4118da07830SSujith Manoharan break;
4128da07830SSujith Manoharan case 0x23: /* LNA1 A+B */
4138da07830SSujith Manoharan ant_conf->fast_div_bias = 0x6;
4148da07830SSujith Manoharan break;
4158da07830SSujith Manoharan case 0x30: /* A+B A-B */
4168da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4178da07830SSujith Manoharan break;
4188da07830SSujith Manoharan case 0x31: /* A+B LNA2 */
4198da07830SSujith Manoharan ant_conf->fast_div_bias = 0x3b;
4208da07830SSujith Manoharan break;
4218da07830SSujith Manoharan case 0x32: /* A+B LNA1 */
4228da07830SSujith Manoharan ant_conf->fast_div_bias = 0x3d;
4238da07830SSujith Manoharan break;
4248da07830SSujith Manoharan default:
4258da07830SSujith Manoharan break;
4268da07830SSujith Manoharan }
4278da07830SSujith Manoharan } else if (ant_conf->div_group == 1) {
4288da07830SSujith Manoharan /* Adjust the fast_div_bias based on main and alt_lna_conf */
4298da07830SSujith Manoharan switch ((ant_conf->main_lna_conf << 4) |
4308da07830SSujith Manoharan ant_conf->alt_lna_conf) {
4318da07830SSujith Manoharan case 0x01: /* A-B LNA2 */
4328da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4338da07830SSujith Manoharan break;
4348da07830SSujith Manoharan case 0x02: /* A-B LNA1 */
4358da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4368da07830SSujith Manoharan break;
4378da07830SSujith Manoharan case 0x03: /* A-B A+B */
4388da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4398da07830SSujith Manoharan break;
4408da07830SSujith Manoharan case 0x10: /* LNA2 A-B */
4418da07830SSujith Manoharan if (!(antcomb->scan) &&
4428da07830SSujith Manoharan (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
4438da07830SSujith Manoharan ant_conf->fast_div_bias = 0x3f;
4448da07830SSujith Manoharan else
4458da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4468da07830SSujith Manoharan break;
4478da07830SSujith Manoharan case 0x12: /* LNA2 LNA1 */
4488da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4498da07830SSujith Manoharan break;
4508da07830SSujith Manoharan case 0x13: /* LNA2 A+B */
4518da07830SSujith Manoharan if (!(antcomb->scan) &&
4528da07830SSujith Manoharan (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
4538da07830SSujith Manoharan ant_conf->fast_div_bias = 0x3f;
4548da07830SSujith Manoharan else
4558da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4568da07830SSujith Manoharan break;
4578da07830SSujith Manoharan case 0x20: /* LNA1 A-B */
4588da07830SSujith Manoharan if (!(antcomb->scan) &&
4598da07830SSujith Manoharan (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
4608da07830SSujith Manoharan ant_conf->fast_div_bias = 0x3f;
4618da07830SSujith Manoharan else
4628da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4638da07830SSujith Manoharan break;
4648da07830SSujith Manoharan case 0x21: /* LNA1 LNA2 */
4658da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4668da07830SSujith Manoharan break;
4678da07830SSujith Manoharan case 0x23: /* LNA1 A+B */
4688da07830SSujith Manoharan if (!(antcomb->scan) &&
4698da07830SSujith Manoharan (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
4708da07830SSujith Manoharan ant_conf->fast_div_bias = 0x3f;
4718da07830SSujith Manoharan else
4728da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4738da07830SSujith Manoharan break;
4748da07830SSujith Manoharan case 0x30: /* A+B A-B */
4758da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4768da07830SSujith Manoharan break;
4778da07830SSujith Manoharan case 0x31: /* A+B LNA2 */
4788da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4798da07830SSujith Manoharan break;
4808da07830SSujith Manoharan case 0x32: /* A+B LNA1 */
4818da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4828da07830SSujith Manoharan break;
4838da07830SSujith Manoharan default:
4848da07830SSujith Manoharan break;
4858da07830SSujith Manoharan }
4868da07830SSujith Manoharan } else if (ant_conf->div_group == 2) {
4878da07830SSujith Manoharan /* Adjust the fast_div_bias based on main and alt_lna_conf */
4888da07830SSujith Manoharan switch ((ant_conf->main_lna_conf << 4) |
4898da07830SSujith Manoharan ant_conf->alt_lna_conf) {
4908da07830SSujith Manoharan case 0x01: /* A-B LNA2 */
4918da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4928da07830SSujith Manoharan break;
4938da07830SSujith Manoharan case 0x02: /* A-B LNA1 */
4948da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4958da07830SSujith Manoharan break;
4968da07830SSujith Manoharan case 0x03: /* A-B A+B */
4978da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
4988da07830SSujith Manoharan break;
4998da07830SSujith Manoharan case 0x10: /* LNA2 A-B */
5003afa6b4fSSujith Manoharan if (!antcomb->scan && (alt_ratio > antcomb->ant_ratio))
5018da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
5028da07830SSujith Manoharan else
5038da07830SSujith Manoharan ant_conf->fast_div_bias = 0x2;
5048da07830SSujith Manoharan break;
5058da07830SSujith Manoharan case 0x12: /* LNA2 LNA1 */
5068da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
5078da07830SSujith Manoharan break;
5088da07830SSujith Manoharan case 0x13: /* LNA2 A+B */
5093afa6b4fSSujith Manoharan if (!antcomb->scan && (alt_ratio > antcomb->ant_ratio))
5108da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
5118da07830SSujith Manoharan else
5128da07830SSujith Manoharan ant_conf->fast_div_bias = 0x2;
5138da07830SSujith Manoharan break;
5148da07830SSujith Manoharan case 0x20: /* LNA1 A-B */
5153afa6b4fSSujith Manoharan if (!antcomb->scan && (alt_ratio > antcomb->ant_ratio))
5168da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
5178da07830SSujith Manoharan else
5188da07830SSujith Manoharan ant_conf->fast_div_bias = 0x2;
5198da07830SSujith Manoharan break;
5208da07830SSujith Manoharan case 0x21: /* LNA1 LNA2 */
5218da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
5228da07830SSujith Manoharan break;
5238da07830SSujith Manoharan case 0x23: /* LNA1 A+B */
5243afa6b4fSSujith Manoharan if (!antcomb->scan && (alt_ratio > antcomb->ant_ratio))
5258da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
5268da07830SSujith Manoharan else
5278da07830SSujith Manoharan ant_conf->fast_div_bias = 0x2;
5288da07830SSujith Manoharan break;
5298da07830SSujith Manoharan case 0x30: /* A+B A-B */
5308da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
5318da07830SSujith Manoharan break;
5328da07830SSujith Manoharan case 0x31: /* A+B LNA2 */
5338da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
5348da07830SSujith Manoharan break;
5358da07830SSujith Manoharan case 0x32: /* A+B LNA1 */
5368da07830SSujith Manoharan ant_conf->fast_div_bias = 0x1;
5378da07830SSujith Manoharan break;
5388da07830SSujith Manoharan default:
5398da07830SSujith Manoharan break;
5408da07830SSujith Manoharan }
5413afa6b4fSSujith Manoharan
5423afa6b4fSSujith Manoharan if (antcomb->fast_div_bias)
5433afa6b4fSSujith Manoharan ant_conf->fast_div_bias = antcomb->fast_div_bias;
5445317c9c3SSujith Manoharan } else if (ant_conf->div_group == 3) {
5455317c9c3SSujith Manoharan switch ((ant_conf->main_lna_conf << 4) |
5465317c9c3SSujith Manoharan ant_conf->alt_lna_conf) {
5475317c9c3SSujith Manoharan case 0x01: /* A-B LNA2 */
5485317c9c3SSujith Manoharan ant_conf->fast_div_bias = 0x1;
5495317c9c3SSujith Manoharan break;
5505317c9c3SSujith Manoharan case 0x02: /* A-B LNA1 */
5515317c9c3SSujith Manoharan ant_conf->fast_div_bias = 0x39;
5525317c9c3SSujith Manoharan break;
5535317c9c3SSujith Manoharan case 0x03: /* A-B A+B */
5545317c9c3SSujith Manoharan ant_conf->fast_div_bias = 0x1;
5555317c9c3SSujith Manoharan break;
5565317c9c3SSujith Manoharan case 0x10: /* LNA2 A-B */
557f96bd2adSSujith Manoharan ant_conf->fast_div_bias = 0x2;
5585317c9c3SSujith Manoharan break;
5595317c9c3SSujith Manoharan case 0x12: /* LNA2 LNA1 */
560f96bd2adSSujith Manoharan ant_conf->fast_div_bias = 0x3f;
5615317c9c3SSujith Manoharan break;
5625317c9c3SSujith Manoharan case 0x13: /* LNA2 A+B */
563f96bd2adSSujith Manoharan ant_conf->fast_div_bias = 0x2;
5645317c9c3SSujith Manoharan break;
5655317c9c3SSujith Manoharan case 0x20: /* LNA1 A-B */
566f96bd2adSSujith Manoharan ant_conf->fast_div_bias = 0x3;
5675317c9c3SSujith Manoharan break;
5685317c9c3SSujith Manoharan case 0x21: /* LNA1 LNA2 */
569f96bd2adSSujith Manoharan ant_conf->fast_div_bias = 0x3;
5705317c9c3SSujith Manoharan break;
5715317c9c3SSujith Manoharan case 0x23: /* LNA1 A+B */
572f96bd2adSSujith Manoharan ant_conf->fast_div_bias = 0x3;
5735317c9c3SSujith Manoharan break;
5745317c9c3SSujith Manoharan case 0x30: /* A+B A-B */
5755317c9c3SSujith Manoharan ant_conf->fast_div_bias = 0x1;
5765317c9c3SSujith Manoharan break;
5775317c9c3SSujith Manoharan case 0x31: /* A+B LNA2 */
5785317c9c3SSujith Manoharan ant_conf->fast_div_bias = 0x6;
5795317c9c3SSujith Manoharan break;
5805317c9c3SSujith Manoharan case 0x32: /* A+B LNA1 */
5815317c9c3SSujith Manoharan ant_conf->fast_div_bias = 0x1;
5825317c9c3SSujith Manoharan break;
5835317c9c3SSujith Manoharan default:
5845317c9c3SSujith Manoharan break;
5855317c9c3SSujith Manoharan }
5868da07830SSujith Manoharan }
5878da07830SSujith Manoharan }
5888da07830SSujith Manoharan
ath_ant_try_scan(struct ath_ant_comb * antcomb,struct ath_hw_antcomb_conf * conf,int curr_alt_set,int alt_rssi_avg,int main_rssi_avg)5895f800ffbSSujith Manoharan static void ath_ant_try_scan(struct ath_ant_comb *antcomb,
5905f800ffbSSujith Manoharan struct ath_hw_antcomb_conf *conf,
5915f800ffbSSujith Manoharan int curr_alt_set, int alt_rssi_avg,
5925f800ffbSSujith Manoharan int main_rssi_avg)
5935f800ffbSSujith Manoharan {
5945f800ffbSSujith Manoharan switch (curr_alt_set) {
5955f800ffbSSujith Manoharan case ATH_ANT_DIV_COMB_LNA2:
5965f800ffbSSujith Manoharan antcomb->rssi_lna2 = alt_rssi_avg;
5975f800ffbSSujith Manoharan antcomb->rssi_lna1 = main_rssi_avg;
5985f800ffbSSujith Manoharan antcomb->scan = true;
5995f800ffbSSujith Manoharan /* set to A+B */
6005f800ffbSSujith Manoharan conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
6015f800ffbSSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
6025f800ffbSSujith Manoharan break;
6035f800ffbSSujith Manoharan case ATH_ANT_DIV_COMB_LNA1:
6045f800ffbSSujith Manoharan antcomb->rssi_lna1 = alt_rssi_avg;
6055f800ffbSSujith Manoharan antcomb->rssi_lna2 = main_rssi_avg;
6065f800ffbSSujith Manoharan antcomb->scan = true;
6075f800ffbSSujith Manoharan /* set to A+B */
6085f800ffbSSujith Manoharan conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
6095f800ffbSSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
6105f800ffbSSujith Manoharan break;
6115f800ffbSSujith Manoharan case ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2:
6125f800ffbSSujith Manoharan antcomb->rssi_add = alt_rssi_avg;
6135f800ffbSSujith Manoharan antcomb->scan = true;
6145f800ffbSSujith Manoharan /* set to A-B */
6155f800ffbSSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
6165f800ffbSSujith Manoharan break;
6175f800ffbSSujith Manoharan case ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2:
6185f800ffbSSujith Manoharan antcomb->rssi_sub = alt_rssi_avg;
6195f800ffbSSujith Manoharan antcomb->scan = false;
6205f800ffbSSujith Manoharan if (antcomb->rssi_lna2 >
621f96bd2adSSujith Manoharan (antcomb->rssi_lna1 + conf->lna1_lna2_switch_delta)) {
6225f800ffbSSujith Manoharan /* use LNA2 as main LNA */
6235f800ffbSSujith Manoharan if ((antcomb->rssi_add > antcomb->rssi_lna1) &&
6245f800ffbSSujith Manoharan (antcomb->rssi_add > antcomb->rssi_sub)) {
6255f800ffbSSujith Manoharan /* set to A+B */
6265f800ffbSSujith Manoharan conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
6275f800ffbSSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
6285f800ffbSSujith Manoharan } else if (antcomb->rssi_sub >
6295f800ffbSSujith Manoharan antcomb->rssi_lna1) {
6305f800ffbSSujith Manoharan /* set to A-B */
6315f800ffbSSujith Manoharan conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
6325f800ffbSSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
6335f800ffbSSujith Manoharan } else {
6345f800ffbSSujith Manoharan /* set to LNA1 */
6355f800ffbSSujith Manoharan conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
6365f800ffbSSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
6375f800ffbSSujith Manoharan }
6385f800ffbSSujith Manoharan } else {
6395f800ffbSSujith Manoharan /* use LNA1 as main LNA */
6405f800ffbSSujith Manoharan if ((antcomb->rssi_add > antcomb->rssi_lna2) &&
6415f800ffbSSujith Manoharan (antcomb->rssi_add > antcomb->rssi_sub)) {
6425f800ffbSSujith Manoharan /* set to A+B */
6435f800ffbSSujith Manoharan conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
6445f800ffbSSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_PLUS_LNA2;
6455f800ffbSSujith Manoharan } else if (antcomb->rssi_sub >
646*15df1981SDmitry Antipov antcomb->rssi_lna2) {
6475f800ffbSSujith Manoharan /* set to A-B */
6485f800ffbSSujith Manoharan conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
6495f800ffbSSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2;
6505f800ffbSSujith Manoharan } else {
6515f800ffbSSujith Manoharan /* set to LNA2 */
6525f800ffbSSujith Manoharan conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
6535f800ffbSSujith Manoharan conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
6545f800ffbSSujith Manoharan }
6555f800ffbSSujith Manoharan }
6565f800ffbSSujith Manoharan break;
6575f800ffbSSujith Manoharan default:
6585f800ffbSSujith Manoharan break;
6595f800ffbSSujith Manoharan }
6605f800ffbSSujith Manoharan }
6615f800ffbSSujith Manoharan
ath_ant_try_switch(struct ath_hw_antcomb_conf * div_ant_conf,struct ath_ant_comb * antcomb,int alt_ratio,int alt_rssi_avg,int main_rssi_avg,int curr_main_set,int curr_alt_set)662ef999114SSujith Manoharan static bool ath_ant_try_switch(struct ath_hw_antcomb_conf *div_ant_conf,
6633afa6b4fSSujith Manoharan struct ath_ant_comb *antcomb,
664ef999114SSujith Manoharan int alt_ratio, int alt_rssi_avg,
665ef999114SSujith Manoharan int main_rssi_avg, int curr_main_set,
666ef999114SSujith Manoharan int curr_alt_set)
667ef999114SSujith Manoharan {
668ef999114SSujith Manoharan bool ret = false;
669ef999114SSujith Manoharan
6703afa6b4fSSujith Manoharan if (ath_ant_div_comb_alt_check(div_ant_conf, antcomb, alt_ratio,
671ef999114SSujith Manoharan alt_rssi_avg, main_rssi_avg)) {
672ef999114SSujith Manoharan if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) {
673ef999114SSujith Manoharan /*
674ef999114SSujith Manoharan * Switch main and alt LNA.
675ef999114SSujith Manoharan */
676ef999114SSujith Manoharan div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA2;
677ef999114SSujith Manoharan div_ant_conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
678ef999114SSujith Manoharan } else if (curr_alt_set == ATH_ANT_DIV_COMB_LNA1) {
679ef999114SSujith Manoharan div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
680ef999114SSujith Manoharan div_ant_conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
681ef999114SSujith Manoharan }
682ef999114SSujith Manoharan
683ef999114SSujith Manoharan ret = true;
684ef999114SSujith Manoharan } else if ((curr_alt_set != ATH_ANT_DIV_COMB_LNA1) &&
685ef999114SSujith Manoharan (curr_alt_set != ATH_ANT_DIV_COMB_LNA2)) {
686ef999114SSujith Manoharan /*
687ef999114SSujith Manoharan Set alt to another LNA.
688ef999114SSujith Manoharan */
689ef999114SSujith Manoharan if (curr_main_set == ATH_ANT_DIV_COMB_LNA2)
690ef999114SSujith Manoharan div_ant_conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA1;
691ef999114SSujith Manoharan else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1)
692ef999114SSujith Manoharan div_ant_conf->alt_lna_conf = ATH_ANT_DIV_COMB_LNA2;
693ef999114SSujith Manoharan
694ef999114SSujith Manoharan ret = true;
695ef999114SSujith Manoharan }
696ef999114SSujith Manoharan
697ef999114SSujith Manoharan return ret;
698ef999114SSujith Manoharan }
699ef999114SSujith Manoharan
ath_ant_short_scan_check(struct ath_ant_comb * antcomb)7009383be42SSujith Manoharan static bool ath_ant_short_scan_check(struct ath_ant_comb *antcomb)
7019383be42SSujith Manoharan {
7029383be42SSujith Manoharan int alt_ratio;
7039383be42SSujith Manoharan
7049383be42SSujith Manoharan if (!antcomb->scan || !antcomb->alt_good)
7059383be42SSujith Manoharan return false;
7069383be42SSujith Manoharan
7079383be42SSujith Manoharan if (time_after(jiffies, antcomb->scan_start_time +
7089383be42SSujith Manoharan msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR)))
7099383be42SSujith Manoharan return true;
7109383be42SSujith Manoharan
7119383be42SSujith Manoharan if (antcomb->total_pkt_count == ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) {
7129383be42SSujith Manoharan alt_ratio = ((antcomb->alt_recv_cnt * 100) /
7139383be42SSujith Manoharan antcomb->total_pkt_count);
7143afa6b4fSSujith Manoharan if (alt_ratio < antcomb->ant_ratio)
7159383be42SSujith Manoharan return true;
7169383be42SSujith Manoharan }
7179383be42SSujith Manoharan
7189383be42SSujith Manoharan return false;
7199383be42SSujith Manoharan }
7209383be42SSujith Manoharan
ath_ant_comb_scan(struct ath_softc * sc,struct ath_rx_status * rs)7218da07830SSujith Manoharan void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
7228da07830SSujith Manoharan {
7238da07830SSujith Manoharan struct ath_hw_antcomb_conf div_ant_conf;
7248da07830SSujith Manoharan struct ath_ant_comb *antcomb = &sc->ant_comb;
7258da07830SSujith Manoharan int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
7268da07830SSujith Manoharan int curr_main_set;
727e45e91d8SFelix Fietkau int main_rssi = rs->rs_rssi_ctl[0];
728e45e91d8SFelix Fietkau int alt_rssi = rs->rs_rssi_ctl[1];
7298da07830SSujith Manoharan int rx_ant_conf, main_ant_conf;
730ef999114SSujith Manoharan bool short_scan = false, ret;
7318da07830SSujith Manoharan
732e45e91d8SFelix Fietkau rx_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_CURRENT_SHIFT) &
7338da07830SSujith Manoharan ATH_ANT_RX_MASK;
734e45e91d8SFelix Fietkau main_ant_conf = (rs->rs_rssi_ctl[2] >> ATH_ANT_RX_MAIN_SHIFT) &
7358da07830SSujith Manoharan ATH_ANT_RX_MASK;
7368da07830SSujith Manoharan
7373afa6b4fSSujith Manoharan if (alt_rssi >= antcomb->low_rssi_thresh) {
7383afa6b4fSSujith Manoharan antcomb->ant_ratio = ATH_ANT_DIV_COMB_ALT_ANT_RATIO;
7393afa6b4fSSujith Manoharan antcomb->ant_ratio2 = ATH_ANT_DIV_COMB_ALT_ANT_RATIO2;
7403afa6b4fSSujith Manoharan } else {
7413afa6b4fSSujith Manoharan antcomb->ant_ratio = ATH_ANT_DIV_COMB_ALT_ANT_RATIO_LOW_RSSI;
7423afa6b4fSSujith Manoharan antcomb->ant_ratio2 = ATH_ANT_DIV_COMB_ALT_ANT_RATIO2_LOW_RSSI;
7433afa6b4fSSujith Manoharan }
7443afa6b4fSSujith Manoharan
7458da07830SSujith Manoharan /* Record packet only when both main_rssi and alt_rssi is positive */
7468da07830SSujith Manoharan if (main_rssi > 0 && alt_rssi > 0) {
7478da07830SSujith Manoharan antcomb->total_pkt_count++;
7488da07830SSujith Manoharan antcomb->main_total_rssi += main_rssi;
7498da07830SSujith Manoharan antcomb->alt_total_rssi += alt_rssi;
7503fbaf4c5SSujith Manoharan
751e3d52914SSujith Manoharan if (main_ant_conf == rx_ant_conf)
7528da07830SSujith Manoharan antcomb->main_recv_cnt++;
753e3d52914SSujith Manoharan else
754e3d52914SSujith Manoharan antcomb->alt_recv_cnt++;
755e3d52914SSujith Manoharan }
756e3d52914SSujith Manoharan
757e3d52914SSujith Manoharan if (main_ant_conf == rx_ant_conf) {
75872569b7bSArnd Bergmann ANT_STAT_INC(sc, ANT_MAIN, recv_cnt);
75972569b7bSArnd Bergmann ANT_LNA_INC(sc, ANT_MAIN, rx_ant_conf);
7603fbaf4c5SSujith Manoharan } else {
76172569b7bSArnd Bergmann ANT_STAT_INC(sc, ANT_ALT, recv_cnt);
76272569b7bSArnd Bergmann ANT_LNA_INC(sc, ANT_ALT, rx_ant_conf);
7633fbaf4c5SSujith Manoharan }
7648da07830SSujith Manoharan
7658da07830SSujith Manoharan /* Short scan check */
7669383be42SSujith Manoharan short_scan = ath_ant_short_scan_check(antcomb);
7678da07830SSujith Manoharan
7688da07830SSujith Manoharan if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) ||
7698da07830SSujith Manoharan rs->rs_moreaggr) && !short_scan)
7708da07830SSujith Manoharan return;
7718da07830SSujith Manoharan
7728da07830SSujith Manoharan if (antcomb->total_pkt_count) {
7738da07830SSujith Manoharan alt_ratio = ((antcomb->alt_recv_cnt * 100) /
7748da07830SSujith Manoharan antcomb->total_pkt_count);
7758da07830SSujith Manoharan main_rssi_avg = (antcomb->main_total_rssi /
7768da07830SSujith Manoharan antcomb->total_pkt_count);
7778da07830SSujith Manoharan alt_rssi_avg = (antcomb->alt_total_rssi /
7788da07830SSujith Manoharan antcomb->total_pkt_count);
7798da07830SSujith Manoharan }
7808da07830SSujith Manoharan
7818da07830SSujith Manoharan ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf);
7828da07830SSujith Manoharan curr_alt_set = div_ant_conf.alt_lna_conf;
7838da07830SSujith Manoharan curr_main_set = div_ant_conf.main_lna_conf;
7848da07830SSujith Manoharan antcomb->count++;
7858da07830SSujith Manoharan
7868da07830SSujith Manoharan if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) {
7873afa6b4fSSujith Manoharan if (alt_ratio > antcomb->ant_ratio) {
7888da07830SSujith Manoharan ath_lnaconf_alt_good_scan(antcomb, div_ant_conf,
7898da07830SSujith Manoharan main_rssi_avg);
7908da07830SSujith Manoharan antcomb->alt_good = true;
7918da07830SSujith Manoharan } else {
7928da07830SSujith Manoharan antcomb->alt_good = false;
7938da07830SSujith Manoharan }
7948da07830SSujith Manoharan
7958da07830SSujith Manoharan antcomb->count = 0;
7968da07830SSujith Manoharan antcomb->scan = true;
7978da07830SSujith Manoharan antcomb->scan_not_start = true;
7988da07830SSujith Manoharan }
7998da07830SSujith Manoharan
8008da07830SSujith Manoharan if (!antcomb->scan) {
8013afa6b4fSSujith Manoharan ret = ath_ant_try_switch(&div_ant_conf, antcomb, alt_ratio,
802ef999114SSujith Manoharan alt_rssi_avg, main_rssi_avg,
803ef999114SSujith Manoharan curr_main_set, curr_alt_set);
804ef999114SSujith Manoharan if (ret)
8058da07830SSujith Manoharan goto div_comb_done;
8068da07830SSujith Manoharan }
8078da07830SSujith Manoharan
808ef999114SSujith Manoharan if (!antcomb->scan &&
809ef999114SSujith Manoharan (alt_rssi_avg < (main_rssi_avg + div_ant_conf.lna1_lna2_delta)))
8108da07830SSujith Manoharan goto div_comb_done;
8118da07830SSujith Manoharan
8128da07830SSujith Manoharan if (!antcomb->scan_not_start) {
8135f800ffbSSujith Manoharan ath_ant_try_scan(antcomb, &div_ant_conf, curr_alt_set,
8145f800ffbSSujith Manoharan alt_rssi_avg, main_rssi_avg);
8158da07830SSujith Manoharan } else {
8168da07830SSujith Manoharan if (!antcomb->alt_good) {
8178da07830SSujith Manoharan antcomb->scan_not_start = false;
8188da07830SSujith Manoharan /* Set alt to another LNA */
8198da07830SSujith Manoharan if (curr_main_set == ATH_ANT_DIV_COMB_LNA2) {
8208da07830SSujith Manoharan div_ant_conf.main_lna_conf =
8218da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA2;
8228da07830SSujith Manoharan div_ant_conf.alt_lna_conf =
8238da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1;
8248da07830SSujith Manoharan } else if (curr_main_set == ATH_ANT_DIV_COMB_LNA1) {
8258da07830SSujith Manoharan div_ant_conf.main_lna_conf =
8268da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA1;
8278da07830SSujith Manoharan div_ant_conf.alt_lna_conf =
8288da07830SSujith Manoharan ATH_ANT_DIV_COMB_LNA2;
8298da07830SSujith Manoharan }
8308da07830SSujith Manoharan goto div_comb_done;
8318da07830SSujith Manoharan }
8328da07830SSujith Manoharan ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf,
8338da07830SSujith Manoharan main_rssi_avg, alt_rssi_avg,
8348da07830SSujith Manoharan alt_ratio);
8358da07830SSujith Manoharan antcomb->quick_scan_cnt++;
8363fbaf4c5SSujith Manoharan }
8378da07830SSujith Manoharan
8388da07830SSujith Manoharan div_comb_done:
8398da07830SSujith Manoharan ath_ant_div_conf_fast_divbias(&div_ant_conf, antcomb, alt_ratio);
8408da07830SSujith Manoharan ath9k_hw_antdiv_comb_conf_set(sc->sc_ah, &div_ant_conf);
841e3d52914SSujith Manoharan ath9k_debug_stat_ant(sc, &div_ant_conf, main_rssi_avg, alt_rssi_avg);
8428da07830SSujith Manoharan
8438da07830SSujith Manoharan antcomb->scan_start_time = jiffies;
8448da07830SSujith Manoharan antcomb->total_pkt_count = 0;
8458da07830SSujith Manoharan antcomb->main_total_rssi = 0;
8468da07830SSujith Manoharan antcomb->alt_total_rssi = 0;
8478da07830SSujith Manoharan antcomb->main_recv_cnt = 0;
8488da07830SSujith Manoharan antcomb->alt_recv_cnt = 0;
8498da07830SSujith Manoharan }
850