|
@@ -68,16 +68,27 @@
|
|
|
* enable_ant_fast_div ==> bit 7
|
|
|
*/
|
|
|
|
|
|
-static inline bool ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta,
|
|
|
+static inline bool 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)
|
|
|
{
|
|
|
- return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
|
|
|
- (alt_rssi_avg > main_rssi_avg + maxdelta)) ||
|
|
|
- (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50);
|
|
|
+ if (pkt_count <= 50)
|
|
|
+ return false;
|
|
|
+
|
|
|
+ if (alt_rssi_avg > main_rssi_avg + mindelta)
|
|
|
+ return true;
|
|
|
+
|
|
|
+ if (alt_ratio >= antcomb->ant_ratio2 &&
|
|
|
+ alt_rssi_avg >= antcomb->low_rssi_thresh &&
|
|
|
+ (alt_rssi_avg > main_rssi_avg + maxdelta))
|
|
|
+ return true;
|
|
|
+
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
static inline bool 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)
|
|
|
{
|
|
@@ -100,20 +111,22 @@ static inline bool ath_ant_div_comb_alt_check(struct ath_hw_antcomb_conf *conf,
|
|
|
break;
|
|
|
case 1:
|
|
|
case 2:
|
|
|
- if (alt_rssi_avg < 4)
|
|
|
+ if (alt_rssi_avg < 4 || alt_rssi_avg < antcomb->low_rssi_thresh)
|
|
|
break;
|
|
|
|
|
|
if ((set1 && (alt_rssi_avg >= (main_rssi_avg - 5))) ||
|
|
|
- (set2 && (alt_rssi_avg >= (main_rssi_avg - 2))))
|
|
|
+ (set2 && (alt_rssi_avg >= (main_rssi_avg - 2))) ||
|
|
|
+ (alt_ratio > antcomb->ant_ratio))
|
|
|
result = true;
|
|
|
|
|
|
break;
|
|
|
case 3:
|
|
|
- if (alt_rssi_avg < 4)
|
|
|
+ if (alt_rssi_avg < 4 || alt_rssi_avg < antcomb->low_rssi_thresh)
|
|
|
break;
|
|
|
|
|
|
if ((set1 && (alt_rssi_avg >= (main_rssi_avg - 3))) ||
|
|
|
- (set2 && (alt_rssi_avg >= (main_rssi_avg + 3))))
|
|
|
+ (set2 && (alt_rssi_avg >= (main_rssi_avg + 3))) ||
|
|
|
+ (alt_ratio > antcomb->ant_ratio))
|
|
|
result = true;
|
|
|
|
|
|
break;
|
|
@@ -266,7 +279,7 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
|
|
|
|
|
|
if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) {
|
|
|
/* main is LNA1 */
|
|
|
- if (ath_is_alt_ant_ratio_better(alt_ratio,
|
|
|
+ if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
|
|
|
ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
|
|
|
ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
|
|
|
main_rssi_avg, alt_rssi_avg,
|
|
@@ -275,7 +288,7 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
|
|
|
else
|
|
|
antcomb->first_ratio = false;
|
|
|
} else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) {
|
|
|
- if (ath_is_alt_ant_ratio_better(alt_ratio,
|
|
|
+ if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
|
|
|
ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
|
|
|
ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
|
|
|
main_rssi_avg, alt_rssi_avg,
|
|
@@ -284,7 +297,7 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
|
|
|
else
|
|
|
antcomb->first_ratio = false;
|
|
|
} else {
|
|
|
- if (ath_is_alt_ant_ratio_better(alt_ratio,
|
|
|
+ if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
|
|
|
ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
|
|
|
0,
|
|
|
main_rssi_avg, alt_rssi_avg,
|
|
@@ -325,7 +338,7 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
|
|
|
div_ant_conf->main_lna_conf = ATH_ANT_DIV_COMB_LNA1;
|
|
|
|
|
|
if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA1) {
|
|
|
- if (ath_is_alt_ant_ratio_better(alt_ratio,
|
|
|
+ if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
|
|
|
ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
|
|
|
ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
|
|
|
main_rssi_avg, alt_rssi_avg,
|
|
@@ -334,7 +347,7 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
|
|
|
else
|
|
|
antcomb->second_ratio = false;
|
|
|
} else if (antcomb->main_conf == ATH_ANT_DIV_COMB_LNA2) {
|
|
|
- if (ath_is_alt_ant_ratio_better(alt_ratio,
|
|
|
+ if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
|
|
|
ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
|
|
|
ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
|
|
|
main_rssi_avg, alt_rssi_avg,
|
|
@@ -343,7 +356,7 @@ static void ath_select_ant_div_from_quick_scan(struct ath_ant_comb *antcomb,
|
|
|
else
|
|
|
antcomb->second_ratio = false;
|
|
|
} else {
|
|
|
- if (ath_is_alt_ant_ratio_better(alt_ratio,
|
|
|
+ if (ath_is_alt_ant_ratio_better(antcomb, alt_ratio,
|
|
|
ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
|
|
|
0,
|
|
|
main_rssi_avg, alt_rssi_avg,
|
|
@@ -484,8 +497,7 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
|
|
|
ant_conf->fast_div_bias = 0x1;
|
|
|
break;
|
|
|
case 0x10: /* LNA2 A-B */
|
|
|
- if (!(antcomb->scan) &&
|
|
|
- (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
|
|
|
+ if (!antcomb->scan && (alt_ratio > antcomb->ant_ratio))
|
|
|
ant_conf->fast_div_bias = 0x1;
|
|
|
else
|
|
|
ant_conf->fast_div_bias = 0x2;
|
|
@@ -494,15 +506,13 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
|
|
|
ant_conf->fast_div_bias = 0x1;
|
|
|
break;
|
|
|
case 0x13: /* LNA2 A+B */
|
|
|
- if (!(antcomb->scan) &&
|
|
|
- (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
|
|
|
+ if (!antcomb->scan && (alt_ratio > antcomb->ant_ratio))
|
|
|
ant_conf->fast_div_bias = 0x1;
|
|
|
else
|
|
|
ant_conf->fast_div_bias = 0x2;
|
|
|
break;
|
|
|
case 0x20: /* LNA1 A-B */
|
|
|
- if (!(antcomb->scan) &&
|
|
|
- (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
|
|
|
+ if (!antcomb->scan && (alt_ratio > antcomb->ant_ratio))
|
|
|
ant_conf->fast_div_bias = 0x1;
|
|
|
else
|
|
|
ant_conf->fast_div_bias = 0x2;
|
|
@@ -511,8 +521,7 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
|
|
|
ant_conf->fast_div_bias = 0x1;
|
|
|
break;
|
|
|
case 0x23: /* LNA1 A+B */
|
|
|
- if (!(antcomb->scan) &&
|
|
|
- (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO))
|
|
|
+ if (!antcomb->scan && (alt_ratio > antcomb->ant_ratio))
|
|
|
ant_conf->fast_div_bias = 0x1;
|
|
|
else
|
|
|
ant_conf->fast_div_bias = 0x2;
|
|
@@ -529,6 +538,9 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf,
|
|
|
default:
|
|
|
break;
|
|
|
}
|
|
|
+
|
|
|
+ if (antcomb->fast_div_bias)
|
|
|
+ ant_conf->fast_div_bias = antcomb->fast_div_bias;
|
|
|
} else if (ant_conf->div_group == 3) {
|
|
|
switch ((ant_conf->main_lna_conf << 4) |
|
|
|
ant_conf->alt_lna_conf) {
|
|
@@ -668,13 +680,14 @@ static void ath_ant_try_scan(struct ath_ant_comb *antcomb,
|
|
|
}
|
|
|
|
|
|
static bool 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)
|
|
|
{
|
|
|
bool ret = false;
|
|
|
|
|
|
- if (ath_ant_div_comb_alt_check(div_ant_conf, alt_ratio,
|
|
|
+ if (ath_ant_div_comb_alt_check(div_ant_conf, antcomb, alt_ratio,
|
|
|
alt_rssi_avg, main_rssi_avg)) {
|
|
|
if (curr_alt_set == ATH_ANT_DIV_COMB_LNA2) {
|
|
|
/*
|
|
@@ -718,7 +731,7 @@ static bool ath_ant_short_scan_check(struct ath_ant_comb *antcomb)
|
|
|
if (antcomb->total_pkt_count == ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) {
|
|
|
alt_ratio = ((antcomb->alt_recv_cnt * 100) /
|
|
|
antcomb->total_pkt_count);
|
|
|
- if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
|
|
|
+ if (alt_ratio < antcomb->ant_ratio)
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -741,6 +754,14 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
|
|
|
main_ant_conf = (rs->rs_rssi_ctl2 >> ATH_ANT_RX_MAIN_SHIFT) &
|
|
|
ATH_ANT_RX_MASK;
|
|
|
|
|
|
+ if (alt_rssi >= antcomb->low_rssi_thresh) {
|
|
|
+ antcomb->ant_ratio = ATH_ANT_DIV_COMB_ALT_ANT_RATIO;
|
|
|
+ antcomb->ant_ratio2 = ATH_ANT_DIV_COMB_ALT_ANT_RATIO2;
|
|
|
+ } else {
|
|
|
+ antcomb->ant_ratio = ATH_ANT_DIV_COMB_ALT_ANT_RATIO_LOW_RSSI;
|
|
|
+ antcomb->ant_ratio2 = ATH_ANT_DIV_COMB_ALT_ANT_RATIO2_LOW_RSSI;
|
|
|
+ }
|
|
|
+
|
|
|
/* Record packet only when both main_rssi and alt_rssi is positive */
|
|
|
if (main_rssi > 0 && alt_rssi > 0) {
|
|
|
antcomb->total_pkt_count++;
|
|
@@ -783,7 +804,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
|
|
|
antcomb->count++;
|
|
|
|
|
|
if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) {
|
|
|
- if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
|
|
|
+ if (alt_ratio > antcomb->ant_ratio) {
|
|
|
ath_lnaconf_alt_good_scan(antcomb, div_ant_conf,
|
|
|
main_rssi_avg);
|
|
|
antcomb->alt_good = true;
|
|
@@ -797,7 +818,7 @@ void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
|
|
|
}
|
|
|
|
|
|
if (!antcomb->scan) {
|
|
|
- ret = ath_ant_try_switch(&div_ant_conf, alt_ratio,
|
|
|
+ ret = ath_ant_try_switch(&div_ant_conf, antcomb, alt_ratio,
|
|
|
alt_rssi_avg, main_rssi_avg,
|
|
|
curr_main_set, curr_alt_set);
|
|
|
if (ret)
|