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 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 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 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 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 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 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 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 > 6465f800ffbSSujith Manoharan antcomb->rssi_lna1) { 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 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 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 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) { 758*72569b7bSArnd Bergmann ANT_STAT_INC(sc, ANT_MAIN, recv_cnt); 759*72569b7bSArnd Bergmann ANT_LNA_INC(sc, ANT_MAIN, rx_ant_conf); 7603fbaf4c5SSujith Manoharan } else { 761*72569b7bSArnd Bergmann ANT_STAT_INC(sc, ANT_ALT, recv_cnt); 762*72569b7bSArnd 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