Deleted Added
full compact
ar9285_diversity.c (251643) ar9285_diversity.c (251655)
1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc.
3 * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*
2 * Copyright (c) 2008-2010 Atheros Communications Inc.
3 * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c 251643 2013-06-12 06:01:53Z adrian $
26 * $FreeBSD: head/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c 251655 2013-06-12 14:52:57Z adrian $
27 */
28#include "opt_ah.h"
29
30#include "ah.h"
31#include "ah_desc.h"
32#include "ah_internal.h"
33#include "ah_eeprom_v4k.h"
34
35#include "ar9002/ar9280.h"
27 */
28#include "opt_ah.h"
29
30#include "ah.h"
31#include "ah_desc.h"
32#include "ah_internal.h"
33#include "ah_eeprom_v4k.h"
34
35#include "ar9002/ar9280.h"
36#include "ar9002/ar9285_diversity.h"
37#include "ar9002/ar9285.h"
38#include "ar5416/ar5416reg.h"
39#include "ar5416/ar5416phy.h"
40#include "ar9002/ar9285phy.h"
41#include "ar9002/ar9285_phy.h"
42
36#include "ar9002/ar9285.h"
37#include "ar5416/ar5416reg.h"
38#include "ar5416/ar5416phy.h"
39#include "ar9002/ar9285phy.h"
40#include "ar9002/ar9285_phy.h"
41
42#include "ar9002/ar9285_diversity.h"
43
43
44/* Linux compability macros */
45/*
44/*
46 * XXX these don't handle rounding, underflow, overflow, wrapping!
47 */
48#define msecs_to_jiffies(a) ( (a) * hz / 1000 )
49#define time_after(a, b) ( (long) (b) - (long) (a) < 0 )
50
51static HAL_BOOL
52ath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, int mindelta,
53 int main_rssi_avg, int alt_rssi_avg, int pkt_count)
54{
55 return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
56 (alt_rssi_avg > main_rssi_avg + maxdelta)) ||
57 (alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50);
58}
59
60static void
61ath_lnaconf_alt_good_scan(struct ar9285_ant_comb *antcomb,
62 HAL_ANT_COMB_CONFIG *ant_conf, int main_rssi_avg)
63{
64 antcomb->quick_scan_cnt = 0;
65
66 if (ant_conf->main_lna_conf == HAL_ANT_DIV_COMB_LNA2)
67 antcomb->rssi_lna2 = main_rssi_avg;
68 else if (ant_conf->main_lna_conf == HAL_ANT_DIV_COMB_LNA1)
69 antcomb->rssi_lna1 = main_rssi_avg;
70
71 switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) {
72 case (0x10): /* LNA2 A-B */
73 antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
74 antcomb->first_quick_scan_conf =
75 HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
76 antcomb->second_quick_scan_conf = HAL_ANT_DIV_COMB_LNA1;
77 break;
78 case (0x20): /* LNA1 A-B */
79 antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
80 antcomb->first_quick_scan_conf =
81 HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
82 antcomb->second_quick_scan_conf = HAL_ANT_DIV_COMB_LNA2;
83 break;
84 case (0x21): /* LNA1 LNA2 */
85 antcomb->main_conf = HAL_ANT_DIV_COMB_LNA2;
86 antcomb->first_quick_scan_conf =
87 HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
88 antcomb->second_quick_scan_conf =
89 HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
90 break;
91 case (0x12): /* LNA2 LNA1 */
92 antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1;
93 antcomb->first_quick_scan_conf =
94 HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
95 antcomb->second_quick_scan_conf =
96 HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
97 break;
98 case (0x13): /* LNA2 A+B */
99 antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
100 antcomb->first_quick_scan_conf =
101 HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
102 antcomb->second_quick_scan_conf = HAL_ANT_DIV_COMB_LNA1;
103 break;
104 case (0x23): /* LNA1 A+B */
105 antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
106 antcomb->first_quick_scan_conf =
107 HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
108 antcomb->second_quick_scan_conf = HAL_ANT_DIV_COMB_LNA2;
109 break;
110 default:
111 break;
112 }
113}
114
115static void
116ath_select_ant_div_from_quick_scan(struct ar9285_ant_comb *antcomb,
117 HAL_ANT_COMB_CONFIG *div_ant_conf, int main_rssi_avg,
118 int alt_rssi_avg, int alt_ratio)
119{
120 /* alt_good */
121 switch (antcomb->quick_scan_cnt) {
122 case 0:
123 /* set alt to main, and alt to first conf */
124 div_ant_conf->main_lna_conf = antcomb->main_conf;
125 div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf;
126 break;
127 case 1:
128 /* set alt to main, and alt to first conf */
129 div_ant_conf->main_lna_conf = antcomb->main_conf;
130 div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf;
131 antcomb->rssi_first = main_rssi_avg;
132 antcomb->rssi_second = alt_rssi_avg;
133
134 if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA1) {
135 /* main is LNA1 */
136 if (ath_is_alt_ant_ratio_better(alt_ratio,
137 ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
138 ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
139 main_rssi_avg, alt_rssi_avg,
140 antcomb->total_pkt_count))
141 antcomb->first_ratio = AH_TRUE;
142 else
143 antcomb->first_ratio = AH_FALSE;
144 } else if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA2) {
145 if (ath_is_alt_ant_ratio_better(alt_ratio,
146 ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
147 ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
148 main_rssi_avg, alt_rssi_avg,
149 antcomb->total_pkt_count))
150 antcomb->first_ratio = AH_TRUE;
151 else
152 antcomb->first_ratio = AH_FALSE;
153 } else {
154 if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
155 (alt_rssi_avg > main_rssi_avg +
156 ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) ||
157 (alt_rssi_avg > main_rssi_avg)) &&
158 (antcomb->total_pkt_count > 50))
159 antcomb->first_ratio = AH_TRUE;
160 else
161 antcomb->first_ratio = AH_FALSE;
162 }
163 break;
164 case 2:
165 antcomb->alt_good = AH_FALSE;
166 antcomb->scan_not_start = AH_FALSE;
167 antcomb->scan = AH_FALSE;
168 antcomb->rssi_first = main_rssi_avg;
169 antcomb->rssi_third = alt_rssi_avg;
170
171 if (antcomb->second_quick_scan_conf == HAL_ANT_DIV_COMB_LNA1)
172 antcomb->rssi_lna1 = alt_rssi_avg;
173 else if (antcomb->second_quick_scan_conf ==
174 HAL_ANT_DIV_COMB_LNA2)
175 antcomb->rssi_lna2 = alt_rssi_avg;
176 else if (antcomb->second_quick_scan_conf ==
177 HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2) {
178 if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA2)
179 antcomb->rssi_lna2 = main_rssi_avg;
180 else if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA1)
181 antcomb->rssi_lna1 = main_rssi_avg;
182 }
183
184 if (antcomb->rssi_lna2 > antcomb->rssi_lna1 +
185 ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)
186 div_ant_conf->main_lna_conf = HAL_ANT_DIV_COMB_LNA2;
187 else
188 div_ant_conf->main_lna_conf = HAL_ANT_DIV_COMB_LNA1;
189
190 if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA1) {
191 if (ath_is_alt_ant_ratio_better(alt_ratio,
192 ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
193 ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
194 main_rssi_avg, alt_rssi_avg,
195 antcomb->total_pkt_count))
196 antcomb->second_ratio = AH_TRUE;
197 else
198 antcomb->second_ratio = AH_FALSE;
199 } else if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA2) {
200 if (ath_is_alt_ant_ratio_better(alt_ratio,
201 ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
202 ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
203 main_rssi_avg, alt_rssi_avg,
204 antcomb->total_pkt_count))
205 antcomb->second_ratio = AH_TRUE;
206 else
207 antcomb->second_ratio = AH_FALSE;
208 } else {
209 if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
210 (alt_rssi_avg > main_rssi_avg +
211 ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) ||
212 (alt_rssi_avg > main_rssi_avg)) &&
213 (antcomb->total_pkt_count > 50))
214 antcomb->second_ratio = AH_TRUE;
215 else
216 antcomb->second_ratio = AH_FALSE;
217 }
218
219 /* set alt to the conf with maximun ratio */
220 if (antcomb->first_ratio && antcomb->second_ratio) {
221 if (antcomb->rssi_second > antcomb->rssi_third) {
222 /* first alt*/
223 if ((antcomb->first_quick_scan_conf ==
224 HAL_ANT_DIV_COMB_LNA1) ||
225 (antcomb->first_quick_scan_conf ==
226 HAL_ANT_DIV_COMB_LNA2))
227 /* Set alt LNA1 or LNA2*/
228 if (div_ant_conf->main_lna_conf ==
229 HAL_ANT_DIV_COMB_LNA2)
230 div_ant_conf->alt_lna_conf =
231 HAL_ANT_DIV_COMB_LNA1;
232 else
233 div_ant_conf->alt_lna_conf =
234 HAL_ANT_DIV_COMB_LNA2;
235 else
236 /* Set alt to A+B or A-B */
237 div_ant_conf->alt_lna_conf =
238 antcomb->first_quick_scan_conf;
239 } else if ((antcomb->second_quick_scan_conf ==
240 HAL_ANT_DIV_COMB_LNA1) ||
241 (antcomb->second_quick_scan_conf ==
242 HAL_ANT_DIV_COMB_LNA2)) {
243 /* Set alt LNA1 or LNA2 */
244 if (div_ant_conf->main_lna_conf ==
245 HAL_ANT_DIV_COMB_LNA2)
246 div_ant_conf->alt_lna_conf =
247 HAL_ANT_DIV_COMB_LNA1;
248 else
249 div_ant_conf->alt_lna_conf =
250 HAL_ANT_DIV_COMB_LNA2;
251 } else {
252 /* Set alt to A+B or A-B */
253 div_ant_conf->alt_lna_conf =
254 antcomb->second_quick_scan_conf;
255 }
256 } else if (antcomb->first_ratio) {
257 /* first alt */
258 if ((antcomb->first_quick_scan_conf ==
259 HAL_ANT_DIV_COMB_LNA1) ||
260 (antcomb->first_quick_scan_conf ==
261 HAL_ANT_DIV_COMB_LNA2))
262 /* Set alt LNA1 or LNA2 */
263 if (div_ant_conf->main_lna_conf ==
264 HAL_ANT_DIV_COMB_LNA2)
265 div_ant_conf->alt_lna_conf =
266 HAL_ANT_DIV_COMB_LNA1;
267 else
268 div_ant_conf->alt_lna_conf =
269 HAL_ANT_DIV_COMB_LNA2;
270 else
271 /* Set alt to A+B or A-B */
272 div_ant_conf->alt_lna_conf =
273 antcomb->first_quick_scan_conf;
274 } else if (antcomb->second_ratio) {
275 /* second alt */
276 if ((antcomb->second_quick_scan_conf ==
277 HAL_ANT_DIV_COMB_LNA1) ||
278 (antcomb->second_quick_scan_conf ==
279 HAL_ANT_DIV_COMB_LNA2))
280 /* Set alt LNA1 or LNA2 */
281 if (div_ant_conf->main_lna_conf ==
282 HAL_ANT_DIV_COMB_LNA2)
283 div_ant_conf->alt_lna_conf =
284 HAL_ANT_DIV_COMB_LNA1;
285 else
286 div_ant_conf->alt_lna_conf =
287 HAL_ANT_DIV_COMB_LNA2;
288 else
289 /* Set alt to A+B or A-B */
290 div_ant_conf->alt_lna_conf =
291 antcomb->second_quick_scan_conf;
292 } else {
293 /* main is largest */
294 if ((antcomb->main_conf == HAL_ANT_DIV_COMB_LNA1) ||
295 (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA2))
296 /* Set alt LNA1 or LNA2 */
297 if (div_ant_conf->main_lna_conf ==
298 HAL_ANT_DIV_COMB_LNA2)
299 div_ant_conf->alt_lna_conf =
300 HAL_ANT_DIV_COMB_LNA1;
301 else
302 div_ant_conf->alt_lna_conf =
303 HAL_ANT_DIV_COMB_LNA2;
304 else
305 /* Set alt to A+B or A-B */
306 div_ant_conf->alt_lna_conf = antcomb->main_conf;
307 }
308 break;
309 default:
310 break;
311 }
312}
313
314static void
315ath_ant_div_conf_fast_divbias(HAL_ANT_COMB_CONFIG *ant_conf)
316{
317 /* Adjust the fast_div_bias based on main and alt lna conf */
318 switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) {
319 case (0x01): /* A-B LNA2 */
320 ant_conf->fast_div_bias = 0x3b;
321 break;
322 case (0x02): /* A-B LNA1 */
323 ant_conf->fast_div_bias = 0x3d;
324 break;
325 case (0x03): /* A-B A+B */
326 ant_conf->fast_div_bias = 0x1;
327 break;
328 case (0x10): /* LNA2 A-B */
329 ant_conf->fast_div_bias = 0x7;
330 break;
331 case (0x12): /* LNA2 LNA1 */
332 ant_conf->fast_div_bias = 0x2;
333 break;
334 case (0x13): /* LNA2 A+B */
335 ant_conf->fast_div_bias = 0x7;
336 break;
337 case (0x20): /* LNA1 A-B */
338 ant_conf->fast_div_bias = 0x6;
339 break;
340 case (0x21): /* LNA1 LNA2 */
341 ant_conf->fast_div_bias = 0x0;
342 break;
343 case (0x23): /* LNA1 A+B */
344 ant_conf->fast_div_bias = 0x6;
345 break;
346 case (0x30): /* A+B A-B */
347 ant_conf->fast_div_bias = 0x1;
348 break;
349 case (0x31): /* A+B LNA2 */
350 ant_conf->fast_div_bias = 0x3b;
351 break;
352 case (0x32): /* A+B LNA1 */
353 ant_conf->fast_div_bias = 0x3d;
354 break;
355 default:
356 break;
357 }
358}
359
360/* Antenna diversity and combining */
361void
362ar9285_ant_comb_scan(struct ath_hal *ah, struct ath_rx_status *rs,
363 unsigned long ticks, int hz)
364{
365 HAL_ANT_COMB_CONFIG div_ant_conf;
366 struct ar9285_ant_comb *antcomb = &AH9285(ah)->ant_comb;
367 int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
368 int curr_main_set, curr_bias;
369 int main_rssi = rs->rs_rssi_ctl[0];
370 int alt_rssi = rs->rs_rssi_ctl[1];
371 int rx_ant_conf, main_ant_conf, alt_ant_conf;
372 HAL_BOOL short_scan = AH_FALSE;
373
374 rx_ant_conf = (rs->rs_rssi_ctl[2] >> 4) & ATH_ANT_RX_MASK;
375 main_ant_conf = (rs->rs_rssi_ctl[2] >> 2) & ATH_ANT_RX_MASK;
376 alt_ant_conf = (rs->rs_rssi_ctl[2] >> 0) & ATH_ANT_RX_MASK;
377
378#if 0
379 HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: RSSI %d/%d, conf %x/%x, rxconf %x, LNA: %d; ANT: %d; FastDiv: %d\n",
380 __func__, main_rssi, alt_rssi, main_ant_conf,alt_ant_conf, rx_ant_conf,
381 !!(rs->rs_rssi_ctl[2] & 0x80), !!(rs->rs_rssi_ctl[2] & 0x40), !!(rs->rs_rssi_ext[2] & 0x40));
382#endif
383
384 if (! ar9285_check_div_comb(ah))
385 return;
386
387 if (AH5212(ah)->ah_diversity == AH_FALSE)
388 return;
389
390#if 0
391 HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main: %d, alt: %d, rx_ant_conf: %x, main_ant_conf: %x\n",
392 __func__, main_rssi, alt_rssi, rx_ant_conf, main_ant_conf);
393#endif
394
395 /* Record packet only when alt_rssi is positive */
396 if (main_rssi > 0 && alt_rssi > 0) {
397 antcomb->total_pkt_count++;
398 antcomb->main_total_rssi += main_rssi;
399 antcomb->alt_total_rssi += alt_rssi;
400 if (main_ant_conf == rx_ant_conf)
401 antcomb->main_recv_cnt++;
402 else
403 antcomb->alt_recv_cnt++;
404 }
405
406 /* Short scan check */
407 if (antcomb->scan && antcomb->alt_good) {
408 if (time_after(ticks, antcomb->scan_start_time +
409 msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR)))
410 short_scan = AH_TRUE;
411 else
412 if (antcomb->total_pkt_count ==
413 ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) {
414 alt_ratio = ((antcomb->alt_recv_cnt * 100) /
415 antcomb->total_pkt_count);
416 if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
417 short_scan = AH_TRUE;
418 }
419 }
420
421 if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) ||
422 rs->rs_moreaggr) && !short_scan)
423 return;
424
425 if (antcomb->total_pkt_count) {
426 alt_ratio = ((antcomb->alt_recv_cnt * 100) /
427 antcomb->total_pkt_count);
428 main_rssi_avg = (antcomb->main_total_rssi /
429 antcomb->total_pkt_count);
430 alt_rssi_avg = (antcomb->alt_total_rssi /
431 antcomb->total_pkt_count);
432 }
433
434 OS_MEMZERO(&div_ant_conf, sizeof(div_ant_conf));
435 ar9285_antdiv_comb_conf_get(ah, &div_ant_conf);
436 curr_alt_set = div_ant_conf.alt_lna_conf;
437 curr_main_set = div_ant_conf.main_lna_conf;
438 curr_bias = div_ant_conf.fast_div_bias;
439
440 antcomb->count++;
441
442 if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) {
443 if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
444 ath_lnaconf_alt_good_scan(antcomb, &div_ant_conf,
445 main_rssi_avg);
446 antcomb->alt_good = AH_TRUE;
447 } else {
448 antcomb->alt_good = AH_FALSE;
449 }
450
451 antcomb->count = 0;
452 antcomb->scan = AH_TRUE;
453 antcomb->scan_not_start = AH_TRUE;
454 }
455
456 if (!antcomb->scan) {
457 if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
458 if (curr_alt_set == HAL_ANT_DIV_COMB_LNA2) {
459 /* Switch main and alt LNA */
460 div_ant_conf.main_lna_conf =
461 HAL_ANT_DIV_COMB_LNA2;
462 div_ant_conf.alt_lna_conf =
463 HAL_ANT_DIV_COMB_LNA1;
464 } else if (curr_alt_set == HAL_ANT_DIV_COMB_LNA1) {
465 div_ant_conf.main_lna_conf =
466 HAL_ANT_DIV_COMB_LNA1;
467 div_ant_conf.alt_lna_conf =
468 HAL_ANT_DIV_COMB_LNA2;
469 }
470
471 goto div_comb_done;
472 } else if ((curr_alt_set != HAL_ANT_DIV_COMB_LNA1) &&
473 (curr_alt_set != HAL_ANT_DIV_COMB_LNA2)) {
474 /* Set alt to another LNA */
475 if (curr_main_set == HAL_ANT_DIV_COMB_LNA2)
476 div_ant_conf.alt_lna_conf =
477 HAL_ANT_DIV_COMB_LNA1;
478 else if (curr_main_set == HAL_ANT_DIV_COMB_LNA1)
479 div_ant_conf.alt_lna_conf =
480 HAL_ANT_DIV_COMB_LNA2;
481
482 goto div_comb_done;
483 }
484
485 if ((alt_rssi_avg < (main_rssi_avg +
486 ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA)))
487 goto div_comb_done;
488 }
489
490 if (!antcomb->scan_not_start) {
491 switch (curr_alt_set) {
492 case HAL_ANT_DIV_COMB_LNA2:
493 antcomb->rssi_lna2 = alt_rssi_avg;
494 antcomb->rssi_lna1 = main_rssi_avg;
495 antcomb->scan = AH_TRUE;
496 /* set to A+B */
497 div_ant_conf.main_lna_conf =
498 HAL_ANT_DIV_COMB_LNA1;
499 div_ant_conf.alt_lna_conf =
500 HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
501 break;
502 case HAL_ANT_DIV_COMB_LNA1:
503 antcomb->rssi_lna1 = alt_rssi_avg;
504 antcomb->rssi_lna2 = main_rssi_avg;
505 antcomb->scan = AH_TRUE;
506 /* set to A+B */
507 div_ant_conf.main_lna_conf = HAL_ANT_DIV_COMB_LNA2;
508 div_ant_conf.alt_lna_conf =
509 HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
510 break;
511 case HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2:
512 antcomb->rssi_add = alt_rssi_avg;
513 antcomb->scan = AH_TRUE;
514 /* set to A-B */
515 div_ant_conf.alt_lna_conf =
516 HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
517 break;
518 case HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2:
519 antcomb->rssi_sub = alt_rssi_avg;
520 antcomb->scan = AH_FALSE;
521 if (antcomb->rssi_lna2 >
522 (antcomb->rssi_lna1 +
523 ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) {
524 /* use LNA2 as main LNA */
525 if ((antcomb->rssi_add > antcomb->rssi_lna1) &&
526 (antcomb->rssi_add > antcomb->rssi_sub)) {
527 /* set to A+B */
528 div_ant_conf.main_lna_conf =
529 HAL_ANT_DIV_COMB_LNA2;
530 div_ant_conf.alt_lna_conf =
531 HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
532 } else if (antcomb->rssi_sub >
533 antcomb->rssi_lna1) {
534 /* set to A-B */
535 div_ant_conf.main_lna_conf =
536 HAL_ANT_DIV_COMB_LNA2;
537 div_ant_conf.alt_lna_conf =
538 HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
539 } else {
540 /* set to LNA1 */
541 div_ant_conf.main_lna_conf =
542 HAL_ANT_DIV_COMB_LNA2;
543 div_ant_conf.alt_lna_conf =
544 HAL_ANT_DIV_COMB_LNA1;
545 }
546 } else {
547 /* use LNA1 as main LNA */
548 if ((antcomb->rssi_add > antcomb->rssi_lna2) &&
549 (antcomb->rssi_add > antcomb->rssi_sub)) {
550 /* set to A+B */
551 div_ant_conf.main_lna_conf =
552 HAL_ANT_DIV_COMB_LNA1;
553 div_ant_conf.alt_lna_conf =
554 HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
555 } else if (antcomb->rssi_sub >
556 antcomb->rssi_lna1) {
557 /* set to A-B */
558 div_ant_conf.main_lna_conf =
559 HAL_ANT_DIV_COMB_LNA1;
560 div_ant_conf.alt_lna_conf =
561 HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
562 } else {
563 /* set to LNA2 */
564 div_ant_conf.main_lna_conf =
565 HAL_ANT_DIV_COMB_LNA1;
566 div_ant_conf.alt_lna_conf =
567 HAL_ANT_DIV_COMB_LNA2;
568 }
569 }
570 break;
571 default:
572 break;
573 }
574 } else {
575 if (!antcomb->alt_good) {
576 antcomb->scan_not_start = AH_FALSE;
577 /* Set alt to another LNA */
578 if (curr_main_set == HAL_ANT_DIV_COMB_LNA2) {
579 div_ant_conf.main_lna_conf =
580 HAL_ANT_DIV_COMB_LNA2;
581 div_ant_conf.alt_lna_conf =
582 HAL_ANT_DIV_COMB_LNA1;
583 } else if (curr_main_set == HAL_ANT_DIV_COMB_LNA1) {
584 div_ant_conf.main_lna_conf =
585 HAL_ANT_DIV_COMB_LNA1;
586 div_ant_conf.alt_lna_conf =
587 HAL_ANT_DIV_COMB_LNA2;
588 }
589 goto div_comb_done;
590 }
591 }
592
593 ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf,
594 main_rssi_avg, alt_rssi_avg,
595 alt_ratio);
596
597 antcomb->quick_scan_cnt++;
598
599div_comb_done:
600 ath_ant_div_conf_fast_divbias(&div_ant_conf);
601
602 ar9285_antdiv_comb_conf_set(ah, &div_ant_conf);
603
604 HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: total_pkt_count=%d\n",
605 __func__, antcomb->total_pkt_count);
606
607 HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main_total_rssi=%d\n",
608 __func__, antcomb->main_total_rssi);
609 HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: alt_total_rssi=%d\n",
610 __func__, antcomb->alt_total_rssi);
611
612 HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main_rssi_avg=%d\n",
613 __func__, main_rssi_avg);
614 HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: alt_alt_rssi_avg=%d\n",
615 __func__, alt_rssi_avg);
616
617 HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main_recv_cnt=%d\n",
618 __func__, antcomb->main_recv_cnt);
619 HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: alt_recv_cnt=%d\n",
620 __func__, antcomb->alt_recv_cnt);
621
622// if (curr_alt_set != div_ant_conf.alt_lna_conf)
623 HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: lna_conf: %x -> %x\n",
624 __func__, curr_alt_set, div_ant_conf.alt_lna_conf);
625// if (curr_main_set != div_ant_conf.main_lna_conf)
626 HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main_lna_conf: %x -> %x\n",
627 __func__, curr_main_set, div_ant_conf.main_lna_conf);
628// if (curr_bias != div_ant_conf.fast_div_bias)
629 HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: fast_div_bias: %x -> %x\n",
630 __func__, curr_bias, div_ant_conf.fast_div_bias);
631
632 antcomb->scan_start_time = ticks;
633 antcomb->total_pkt_count = 0;
634 antcomb->main_total_rssi = 0;
635 antcomb->alt_total_rssi = 0;
636 antcomb->main_recv_cnt = 0;
637 antcomb->alt_recv_cnt = 0;
638}
639
640/*
641 * Set the antenna switch to control RX antenna diversity.
642 *
643 * If a fixed configuration is used, the LNA and div bias
644 * settings are fixed and the antenna diversity scanning routine
645 * is disabled.
646 *
647 * If a variable configuration is used, a default is programmed
648 * in and sampling commences per RXed packet.

--- 104 unchanged lines hidden ---
45 * Set the antenna switch to control RX antenna diversity.
46 *
47 * If a fixed configuration is used, the LNA and div bias
48 * settings are fixed and the antenna diversity scanning routine
49 * is disabled.
50 *
51 * If a variable configuration is used, a default is programmed
52 * in and sampling commences per RXed packet.

--- 104 unchanged lines hidden ---