ar9285_diversity.c revision 239890
1220593Sadrian/*
2220593Sadrian * Copyright (c) 2008-2010 Atheros Communications Inc.
3220593Sadrian * Copyright (c) 2011 Adrian Chadd, Xenion Pty Ltd.
4220593Sadrian *
5220593Sadrian * Redistribution and use in source and binary forms, with or without
6220593Sadrian * modification, are permitted provided that the following conditions
7220593Sadrian * are met:
8220593Sadrian * 1. Redistributions of source code must retain the above copyright
9220593Sadrian *    notice, this list of conditions and the following disclaimer.
10220593Sadrian * 2. Redistributions in binary form must reproduce the above copyright
11220593Sadrian *    notice, this list of conditions and the following disclaimer in the
12220593Sadrian *    documentation and/or other materials provided with the distribution.
13220593Sadrian *
14220593Sadrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15220593Sadrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16220593Sadrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17220593Sadrian * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18220593Sadrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19220593Sadrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20220593Sadrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21220593Sadrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22220593Sadrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23220593Sadrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24220593Sadrian * SUCH DAMAGE.
25220593Sadrian *
26220593Sadrian * $FreeBSD: head/sys/dev/ath/ath_hal/ar9002/ar9285_diversity.c 239890 2012-08-30 06:55:47Z adrian $
27220593Sadrian */
28220593Sadrian#include "opt_ah.h"
29220593Sadrian
30220593Sadrian#include "ah.h"
31220593Sadrian#include "ah_desc.h"
32220593Sadrian#include "ah_internal.h"
33220593Sadrian#include "ah_eeprom_v4k.h"
34220593Sadrian
35220593Sadrian#include "ar9002/ar9280.h"
36220593Sadrian#include "ar9002/ar9285_diversity.h"
37220593Sadrian#include "ar9002/ar9285.h"
38220593Sadrian#include "ar5416/ar5416reg.h"
39220593Sadrian#include "ar5416/ar5416phy.h"
40220593Sadrian#include "ar9002/ar9285phy.h"
41220593Sadrian#include "ar9002/ar9285_phy.h"
42220593Sadrian
43220593Sadrian
44220593Sadrian/* Linux compability macros */
45220593Sadrian/*
46220593Sadrian * XXX these don't handle rounding, underflow, overflow, wrapping!
47220593Sadrian */
48220593Sadrian#define	msecs_to_jiffies(a)		( (a) * hz / 1000 )
49220593Sadrian#define	time_after(a, b)		( (long) (b) - (long) (a) < 0 )
50220593Sadrian
51220593Sadrianstatic HAL_BOOL
52220593Sadrianath_is_alt_ant_ratio_better(int alt_ratio, int maxdelta, int mindelta,
53220593Sadrian    int main_rssi_avg, int alt_rssi_avg, int pkt_count)
54220593Sadrian{
55220593Sadrian	return (((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
56220593Sadrian		(alt_rssi_avg > main_rssi_avg + maxdelta)) ||
57220593Sadrian		(alt_rssi_avg > main_rssi_avg + mindelta)) && (pkt_count > 50);
58220593Sadrian}
59220593Sadrian
60220593Sadrianstatic void
61220593Sadrianath_lnaconf_alt_good_scan(struct ar9285_ant_comb *antcomb,
62220593Sadrian    struct ar9285_antcomb_conf ant_conf, int main_rssi_avg)
63220593Sadrian{
64220593Sadrian	antcomb->quick_scan_cnt = 0;
65220593Sadrian
66239890Sadrian	if (ant_conf.main_lna_conf == HAL_ANT_DIV_COMB_LNA2)
67220593Sadrian		antcomb->rssi_lna2 = main_rssi_avg;
68239890Sadrian	else if (ant_conf.main_lna_conf == HAL_ANT_DIV_COMB_LNA1)
69220593Sadrian		antcomb->rssi_lna1 = main_rssi_avg;
70220593Sadrian
71220593Sadrian	switch ((ant_conf.main_lna_conf << 4) | ant_conf.alt_lna_conf) {
72220593Sadrian	case (0x10): /* LNA2 A-B */
73239890Sadrian		antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
74220593Sadrian		antcomb->first_quick_scan_conf =
75239890Sadrian			HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
76239890Sadrian		antcomb->second_quick_scan_conf = HAL_ANT_DIV_COMB_LNA1;
77220593Sadrian		break;
78220593Sadrian	case (0x20): /* LNA1 A-B */
79239890Sadrian		antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
80220593Sadrian		antcomb->first_quick_scan_conf =
81239890Sadrian			HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
82239890Sadrian		antcomb->second_quick_scan_conf = HAL_ANT_DIV_COMB_LNA2;
83220593Sadrian		break;
84220593Sadrian	case (0x21): /* LNA1 LNA2 */
85239890Sadrian		antcomb->main_conf = HAL_ANT_DIV_COMB_LNA2;
86220593Sadrian		antcomb->first_quick_scan_conf =
87239890Sadrian			HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
88220593Sadrian		antcomb->second_quick_scan_conf =
89239890Sadrian			HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
90220593Sadrian		break;
91220593Sadrian	case (0x12): /* LNA2 LNA1 */
92239890Sadrian		antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1;
93220593Sadrian		antcomb->first_quick_scan_conf =
94239890Sadrian			HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
95220593Sadrian		antcomb->second_quick_scan_conf =
96239890Sadrian			HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
97220593Sadrian		break;
98220593Sadrian	case (0x13): /* LNA2 A+B */
99239890Sadrian		antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
100220593Sadrian		antcomb->first_quick_scan_conf =
101239890Sadrian			HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
102239890Sadrian		antcomb->second_quick_scan_conf = HAL_ANT_DIV_COMB_LNA1;
103220593Sadrian		break;
104220593Sadrian	case (0x23): /* LNA1 A+B */
105239890Sadrian		antcomb->main_conf = HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
106220593Sadrian		antcomb->first_quick_scan_conf =
107239890Sadrian			HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
108239890Sadrian		antcomb->second_quick_scan_conf = HAL_ANT_DIV_COMB_LNA2;
109220593Sadrian		break;
110220593Sadrian	default:
111220593Sadrian		break;
112220593Sadrian	}
113220593Sadrian}
114220593Sadrian
115220593Sadrianstatic void
116220593Sadrianath_select_ant_div_from_quick_scan(struct ar9285_ant_comb *antcomb,
117220593Sadrian    struct ar9285_antcomb_conf *div_ant_conf, int main_rssi_avg,
118220593Sadrian    int alt_rssi_avg, int alt_ratio)
119220593Sadrian{
120220593Sadrian	/* alt_good */
121220593Sadrian	switch (antcomb->quick_scan_cnt) {
122220593Sadrian	case 0:
123220593Sadrian		/* set alt to main, and alt to first conf */
124220593Sadrian		div_ant_conf->main_lna_conf = antcomb->main_conf;
125220593Sadrian		div_ant_conf->alt_lna_conf = antcomb->first_quick_scan_conf;
126220593Sadrian		break;
127220593Sadrian	case 1:
128220593Sadrian		/* set alt to main, and alt to first conf */
129220593Sadrian		div_ant_conf->main_lna_conf = antcomb->main_conf;
130220593Sadrian		div_ant_conf->alt_lna_conf = antcomb->second_quick_scan_conf;
131220593Sadrian		antcomb->rssi_first = main_rssi_avg;
132220593Sadrian		antcomb->rssi_second = alt_rssi_avg;
133220593Sadrian
134239890Sadrian		if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA1) {
135220593Sadrian			/* main is LNA1 */
136220593Sadrian			if (ath_is_alt_ant_ratio_better(alt_ratio,
137220593Sadrian						ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
138220593Sadrian						ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
139220593Sadrian						main_rssi_avg, alt_rssi_avg,
140220593Sadrian						antcomb->total_pkt_count))
141220593Sadrian				antcomb->first_ratio = AH_TRUE;
142220593Sadrian			else
143220593Sadrian				antcomb->first_ratio = AH_FALSE;
144239890Sadrian		} else if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA2) {
145220593Sadrian			if (ath_is_alt_ant_ratio_better(alt_ratio,
146220593Sadrian						ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
147220593Sadrian						ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
148220593Sadrian						main_rssi_avg, alt_rssi_avg,
149220593Sadrian						antcomb->total_pkt_count))
150220593Sadrian				antcomb->first_ratio = AH_TRUE;
151220593Sadrian			else
152220593Sadrian				antcomb->first_ratio = AH_FALSE;
153220593Sadrian		} else {
154220593Sadrian			if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
155220593Sadrian			    (alt_rssi_avg > main_rssi_avg +
156220593Sadrian			    ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) ||
157220593Sadrian			    (alt_rssi_avg > main_rssi_avg)) &&
158220593Sadrian			    (antcomb->total_pkt_count > 50))
159220593Sadrian				antcomb->first_ratio = AH_TRUE;
160220593Sadrian			else
161220593Sadrian				antcomb->first_ratio = AH_FALSE;
162220593Sadrian		}
163220593Sadrian		break;
164220593Sadrian	case 2:
165220593Sadrian		antcomb->alt_good = AH_FALSE;
166220593Sadrian		antcomb->scan_not_start = AH_FALSE;
167220593Sadrian		antcomb->scan = AH_FALSE;
168220593Sadrian		antcomb->rssi_first = main_rssi_avg;
169220593Sadrian		antcomb->rssi_third = alt_rssi_avg;
170220593Sadrian
171239890Sadrian		if (antcomb->second_quick_scan_conf == HAL_ANT_DIV_COMB_LNA1)
172220593Sadrian			antcomb->rssi_lna1 = alt_rssi_avg;
173220593Sadrian		else if (antcomb->second_quick_scan_conf ==
174239890Sadrian			 HAL_ANT_DIV_COMB_LNA2)
175220593Sadrian			antcomb->rssi_lna2 = alt_rssi_avg;
176220593Sadrian		else if (antcomb->second_quick_scan_conf ==
177239890Sadrian			 HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2) {
178239890Sadrian			if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA2)
179220593Sadrian				antcomb->rssi_lna2 = main_rssi_avg;
180239890Sadrian			else if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA1)
181220593Sadrian				antcomb->rssi_lna1 = main_rssi_avg;
182220593Sadrian		}
183220593Sadrian
184220593Sadrian		if (antcomb->rssi_lna2 > antcomb->rssi_lna1 +
185220593Sadrian		    ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)
186239890Sadrian			div_ant_conf->main_lna_conf = HAL_ANT_DIV_COMB_LNA2;
187220593Sadrian		else
188239890Sadrian			div_ant_conf->main_lna_conf = HAL_ANT_DIV_COMB_LNA1;
189220593Sadrian
190239890Sadrian		if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA1) {
191220593Sadrian			if (ath_is_alt_ant_ratio_better(alt_ratio,
192220593Sadrian						ATH_ANT_DIV_COMB_LNA1_DELTA_HI,
193220593Sadrian						ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
194220593Sadrian						main_rssi_avg, alt_rssi_avg,
195220593Sadrian						antcomb->total_pkt_count))
196220593Sadrian				antcomb->second_ratio = AH_TRUE;
197220593Sadrian			else
198220593Sadrian				antcomb->second_ratio = AH_FALSE;
199239890Sadrian		} else if (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA2) {
200220593Sadrian			if (ath_is_alt_ant_ratio_better(alt_ratio,
201220593Sadrian						ATH_ANT_DIV_COMB_LNA1_DELTA_MID,
202220593Sadrian						ATH_ANT_DIV_COMB_LNA1_DELTA_LOW,
203220593Sadrian						main_rssi_avg, alt_rssi_avg,
204220593Sadrian						antcomb->total_pkt_count))
205220593Sadrian				antcomb->second_ratio = AH_TRUE;
206220593Sadrian			else
207220593Sadrian				antcomb->second_ratio = AH_FALSE;
208220593Sadrian		} else {
209220593Sadrian			if ((((alt_ratio >= ATH_ANT_DIV_COMB_ALT_ANT_RATIO2) &&
210220593Sadrian			    (alt_rssi_avg > main_rssi_avg +
211220593Sadrian			    ATH_ANT_DIV_COMB_LNA1_DELTA_HI)) ||
212220593Sadrian			    (alt_rssi_avg > main_rssi_avg)) &&
213220593Sadrian			    (antcomb->total_pkt_count > 50))
214220593Sadrian				antcomb->second_ratio = AH_TRUE;
215220593Sadrian			else
216220593Sadrian				antcomb->second_ratio = AH_FALSE;
217220593Sadrian		}
218220593Sadrian
219220593Sadrian		/* set alt to the conf with maximun ratio */
220220593Sadrian		if (antcomb->first_ratio && antcomb->second_ratio) {
221220593Sadrian			if (antcomb->rssi_second > antcomb->rssi_third) {
222220593Sadrian				/* first alt*/
223220593Sadrian				if ((antcomb->first_quick_scan_conf ==
224239890Sadrian				    HAL_ANT_DIV_COMB_LNA1) ||
225220593Sadrian				    (antcomb->first_quick_scan_conf ==
226239890Sadrian				    HAL_ANT_DIV_COMB_LNA2))
227220593Sadrian					/* Set alt LNA1 or LNA2*/
228220593Sadrian					if (div_ant_conf->main_lna_conf ==
229239890Sadrian					    HAL_ANT_DIV_COMB_LNA2)
230220593Sadrian						div_ant_conf->alt_lna_conf =
231239890Sadrian							HAL_ANT_DIV_COMB_LNA1;
232220593Sadrian					else
233220593Sadrian						div_ant_conf->alt_lna_conf =
234239890Sadrian							HAL_ANT_DIV_COMB_LNA2;
235220593Sadrian				else
236220593Sadrian					/* Set alt to A+B or A-B */
237220593Sadrian					div_ant_conf->alt_lna_conf =
238220593Sadrian						antcomb->first_quick_scan_conf;
239220593Sadrian			} else if ((antcomb->second_quick_scan_conf ==
240239890Sadrian				   HAL_ANT_DIV_COMB_LNA1) ||
241220593Sadrian				   (antcomb->second_quick_scan_conf ==
242239890Sadrian				   HAL_ANT_DIV_COMB_LNA2)) {
243220593Sadrian				/* Set alt LNA1 or LNA2 */
244220593Sadrian				if (div_ant_conf->main_lna_conf ==
245239890Sadrian				    HAL_ANT_DIV_COMB_LNA2)
246220593Sadrian					div_ant_conf->alt_lna_conf =
247239890Sadrian						HAL_ANT_DIV_COMB_LNA1;
248220593Sadrian				else
249220593Sadrian					div_ant_conf->alt_lna_conf =
250239890Sadrian						HAL_ANT_DIV_COMB_LNA2;
251220593Sadrian			} else {
252220593Sadrian				/* Set alt to A+B or A-B */
253220593Sadrian				div_ant_conf->alt_lna_conf =
254220593Sadrian					antcomb->second_quick_scan_conf;
255220593Sadrian			}
256220593Sadrian		} else if (antcomb->first_ratio) {
257220593Sadrian			/* first alt */
258220593Sadrian			if ((antcomb->first_quick_scan_conf ==
259239890Sadrian			    HAL_ANT_DIV_COMB_LNA1) ||
260220593Sadrian			    (antcomb->first_quick_scan_conf ==
261239890Sadrian			    HAL_ANT_DIV_COMB_LNA2))
262220593Sadrian					/* Set alt LNA1 or LNA2 */
263220593Sadrian				if (div_ant_conf->main_lna_conf ==
264239890Sadrian				    HAL_ANT_DIV_COMB_LNA2)
265220593Sadrian					div_ant_conf->alt_lna_conf =
266239890Sadrian							HAL_ANT_DIV_COMB_LNA1;
267220593Sadrian				else
268220593Sadrian					div_ant_conf->alt_lna_conf =
269239890Sadrian							HAL_ANT_DIV_COMB_LNA2;
270220593Sadrian			else
271220593Sadrian				/* Set alt to A+B or A-B */
272220593Sadrian				div_ant_conf->alt_lna_conf =
273220593Sadrian						antcomb->first_quick_scan_conf;
274220593Sadrian		} else if (antcomb->second_ratio) {
275220593Sadrian				/* second alt */
276220593Sadrian			if ((antcomb->second_quick_scan_conf ==
277239890Sadrian			    HAL_ANT_DIV_COMB_LNA1) ||
278220593Sadrian			    (antcomb->second_quick_scan_conf ==
279239890Sadrian			    HAL_ANT_DIV_COMB_LNA2))
280220593Sadrian				/* Set alt LNA1 or LNA2 */
281220593Sadrian				if (div_ant_conf->main_lna_conf ==
282239890Sadrian				    HAL_ANT_DIV_COMB_LNA2)
283220593Sadrian					div_ant_conf->alt_lna_conf =
284239890Sadrian						HAL_ANT_DIV_COMB_LNA1;
285220593Sadrian				else
286220593Sadrian					div_ant_conf->alt_lna_conf =
287239890Sadrian						HAL_ANT_DIV_COMB_LNA2;
288220593Sadrian			else
289220593Sadrian				/* Set alt to A+B or A-B */
290220593Sadrian				div_ant_conf->alt_lna_conf =
291220593Sadrian						antcomb->second_quick_scan_conf;
292220593Sadrian		} else {
293220593Sadrian			/* main is largest */
294239890Sadrian			if ((antcomb->main_conf == HAL_ANT_DIV_COMB_LNA1) ||
295239890Sadrian			    (antcomb->main_conf == HAL_ANT_DIV_COMB_LNA2))
296220593Sadrian				/* Set alt LNA1 or LNA2 */
297220593Sadrian				if (div_ant_conf->main_lna_conf ==
298239890Sadrian				    HAL_ANT_DIV_COMB_LNA2)
299220593Sadrian					div_ant_conf->alt_lna_conf =
300239890Sadrian							HAL_ANT_DIV_COMB_LNA1;
301220593Sadrian				else
302220593Sadrian					div_ant_conf->alt_lna_conf =
303239890Sadrian							HAL_ANT_DIV_COMB_LNA2;
304220593Sadrian			else
305220593Sadrian				/* Set alt to A+B or A-B */
306220593Sadrian				div_ant_conf->alt_lna_conf = antcomb->main_conf;
307220593Sadrian		}
308220593Sadrian		break;
309220593Sadrian	default:
310220593Sadrian		break;
311220593Sadrian	}
312220593Sadrian}
313220593Sadrian
314220593Sadrianstatic void
315220593Sadrianath_ant_div_conf_fast_divbias(struct ar9285_antcomb_conf *ant_conf)
316220593Sadrian{
317220593Sadrian	/* Adjust the fast_div_bias based on main and alt lna conf */
318220593Sadrian	switch ((ant_conf->main_lna_conf << 4) | ant_conf->alt_lna_conf) {
319220593Sadrian	case (0x01): /* A-B LNA2 */
320220593Sadrian		ant_conf->fast_div_bias = 0x3b;
321220593Sadrian		break;
322220593Sadrian	case (0x02): /* A-B LNA1 */
323220593Sadrian		ant_conf->fast_div_bias = 0x3d;
324220593Sadrian		break;
325220593Sadrian	case (0x03): /* A-B A+B */
326220593Sadrian		ant_conf->fast_div_bias = 0x1;
327220593Sadrian		break;
328220593Sadrian	case (0x10): /* LNA2 A-B */
329220593Sadrian		ant_conf->fast_div_bias = 0x7;
330220593Sadrian		break;
331220593Sadrian	case (0x12): /* LNA2 LNA1 */
332220593Sadrian		ant_conf->fast_div_bias = 0x2;
333220593Sadrian		break;
334220593Sadrian	case (0x13): /* LNA2 A+B */
335220593Sadrian		ant_conf->fast_div_bias = 0x7;
336220593Sadrian		break;
337220593Sadrian	case (0x20): /* LNA1 A-B */
338220593Sadrian		ant_conf->fast_div_bias = 0x6;
339220593Sadrian		break;
340220593Sadrian	case (0x21): /* LNA1 LNA2 */
341220593Sadrian		ant_conf->fast_div_bias = 0x0;
342220593Sadrian		break;
343220593Sadrian	case (0x23): /* LNA1 A+B */
344220593Sadrian		ant_conf->fast_div_bias = 0x6;
345220593Sadrian		break;
346220593Sadrian	case (0x30): /* A+B A-B */
347220593Sadrian		ant_conf->fast_div_bias = 0x1;
348220593Sadrian		break;
349220593Sadrian	case (0x31): /* A+B LNA2 */
350220593Sadrian		ant_conf->fast_div_bias = 0x3b;
351220593Sadrian		break;
352220593Sadrian	case (0x32): /* A+B LNA1 */
353220593Sadrian		ant_conf->fast_div_bias = 0x3d;
354220593Sadrian		break;
355220593Sadrian	default:
356220593Sadrian		break;
357220593Sadrian	}
358220593Sadrian}
359220593Sadrian
360220593Sadrian/* Antenna diversity and combining */
361220593Sadrianvoid
362220593Sadrianar9285_ant_comb_scan(struct ath_hal *ah, struct ath_rx_status *rs,
363220593Sadrian    unsigned long ticks, int hz)
364220593Sadrian{
365220593Sadrian	struct ar9285_antcomb_conf div_ant_conf;
366220593Sadrian	struct ar9285_ant_comb *antcomb = &AH9285(ah)->ant_comb;
367220593Sadrian	int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
368220593Sadrian	int curr_main_set, curr_bias;
369220593Sadrian	int main_rssi = rs->rs_rssi_ctl[0];
370220593Sadrian	int alt_rssi = rs->rs_rssi_ctl[1];
371221833Sadrian	int rx_ant_conf, main_ant_conf, alt_ant_conf;
372220593Sadrian	HAL_BOOL short_scan = AH_FALSE;
373220593Sadrian
374221833Sadrian	rx_ant_conf = (rs->rs_rssi_ctl[2] >> 4) & ATH_ANT_RX_MASK;
375221833Sadrian	main_ant_conf = (rs->rs_rssi_ctl[2] >> 2) & ATH_ANT_RX_MASK;
376221833Sadrian	alt_ant_conf = (rs->rs_rssi_ctl[2] >> 0) & ATH_ANT_RX_MASK;
377221833Sadrian
378221833Sadrian#if 0
379221833Sadrian	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: RSSI %d/%d, conf %x/%x, rxconf %x, LNA: %d; ANT: %d; FastDiv: %d\n",
380221833Sadrian	    __func__, main_rssi, alt_rssi, main_ant_conf,alt_ant_conf, rx_ant_conf,
381221833Sadrian	    !!(rs->rs_rssi_ctl[2] & 0x80), !!(rs->rs_rssi_ctl[2] & 0x40), !!(rs->rs_rssi_ext[2] & 0x40));
382221833Sadrian#endif
383221833Sadrian
384220599Sadrian	if (! ar9285_check_div_comb(ah))
385220599Sadrian		return;
386220599Sadrian
387221694Sadrian	if (AH5212(ah)->ah_diversity == AH_FALSE)
388221694Sadrian		return;
389221694Sadrian
390221694Sadrian#if 0
391221694Sadrian	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main: %d, alt: %d, rx_ant_conf: %x, main_ant_conf: %x\n",
392221694Sadrian	    __func__, main_rssi, alt_rssi, rx_ant_conf, main_ant_conf);
393221694Sadrian#endif
394221694Sadrian
395220593Sadrian	/* Record packet only when alt_rssi is positive */
396221833Sadrian	if (main_rssi > 0 && alt_rssi > 0) {
397220593Sadrian		antcomb->total_pkt_count++;
398220593Sadrian		antcomb->main_total_rssi += main_rssi;
399220593Sadrian		antcomb->alt_total_rssi  += alt_rssi;
400220593Sadrian		if (main_ant_conf == rx_ant_conf)
401220593Sadrian			antcomb->main_recv_cnt++;
402220593Sadrian		else
403220593Sadrian			antcomb->alt_recv_cnt++;
404220593Sadrian	}
405220593Sadrian
406220593Sadrian	/* Short scan check */
407220593Sadrian	if (antcomb->scan && antcomb->alt_good) {
408220593Sadrian		if (time_after(ticks, antcomb->scan_start_time +
409220593Sadrian		    msecs_to_jiffies(ATH_ANT_DIV_COMB_SHORT_SCAN_INTR)))
410220593Sadrian			short_scan = AH_TRUE;
411220593Sadrian		else
412220593Sadrian			if (antcomb->total_pkt_count ==
413220593Sadrian			    ATH_ANT_DIV_COMB_SHORT_SCAN_PKTCOUNT) {
414220593Sadrian				alt_ratio = ((antcomb->alt_recv_cnt * 100) /
415220593Sadrian					    antcomb->total_pkt_count);
416220593Sadrian				if (alt_ratio < ATH_ANT_DIV_COMB_ALT_ANT_RATIO)
417220593Sadrian					short_scan = AH_TRUE;
418220593Sadrian			}
419220593Sadrian	}
420220593Sadrian
421220593Sadrian	if (((antcomb->total_pkt_count < ATH_ANT_DIV_COMB_MAX_PKTCOUNT) ||
422220593Sadrian	    rs->rs_moreaggr) && !short_scan)
423220593Sadrian		return;
424220593Sadrian
425220593Sadrian	if (antcomb->total_pkt_count) {
426220593Sadrian		alt_ratio = ((antcomb->alt_recv_cnt * 100) /
427220593Sadrian			     antcomb->total_pkt_count);
428220593Sadrian		main_rssi_avg = (antcomb->main_total_rssi /
429220593Sadrian				 antcomb->total_pkt_count);
430220593Sadrian		alt_rssi_avg = (antcomb->alt_total_rssi /
431220593Sadrian				 antcomb->total_pkt_count);
432220593Sadrian	}
433220593Sadrian
434220593Sadrian	ar9285_antdiv_comb_conf_get(ah, &div_ant_conf);
435220593Sadrian	curr_alt_set = div_ant_conf.alt_lna_conf;
436220593Sadrian	curr_main_set = div_ant_conf.main_lna_conf;
437220593Sadrian	curr_bias = div_ant_conf.fast_div_bias;
438220593Sadrian
439220593Sadrian	antcomb->count++;
440220593Sadrian
441220593Sadrian	if (antcomb->count == ATH_ANT_DIV_COMB_MAX_COUNT) {
442220593Sadrian		if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
443220593Sadrian			ath_lnaconf_alt_good_scan(antcomb, div_ant_conf,
444220593Sadrian						  main_rssi_avg);
445220593Sadrian			antcomb->alt_good = AH_TRUE;
446220593Sadrian		} else {
447220593Sadrian			antcomb->alt_good = AH_FALSE;
448220593Sadrian		}
449220593Sadrian
450220593Sadrian		antcomb->count = 0;
451220593Sadrian		antcomb->scan = AH_TRUE;
452220593Sadrian		antcomb->scan_not_start = AH_TRUE;
453220593Sadrian	}
454220593Sadrian
455220593Sadrian	if (!antcomb->scan) {
456220593Sadrian		if (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO) {
457239890Sadrian			if (curr_alt_set == HAL_ANT_DIV_COMB_LNA2) {
458220593Sadrian				/* Switch main and alt LNA */
459220593Sadrian				div_ant_conf.main_lna_conf =
460239890Sadrian						HAL_ANT_DIV_COMB_LNA2;
461220593Sadrian				div_ant_conf.alt_lna_conf  =
462239890Sadrian						HAL_ANT_DIV_COMB_LNA1;
463239890Sadrian			} else if (curr_alt_set == HAL_ANT_DIV_COMB_LNA1) {
464220593Sadrian				div_ant_conf.main_lna_conf =
465239890Sadrian						HAL_ANT_DIV_COMB_LNA1;
466220593Sadrian				div_ant_conf.alt_lna_conf  =
467239890Sadrian						HAL_ANT_DIV_COMB_LNA2;
468220593Sadrian			}
469220593Sadrian
470220593Sadrian			goto div_comb_done;
471239890Sadrian		} else if ((curr_alt_set != HAL_ANT_DIV_COMB_LNA1) &&
472239890Sadrian			   (curr_alt_set != HAL_ANT_DIV_COMB_LNA2)) {
473220593Sadrian			/* Set alt to another LNA */
474239890Sadrian			if (curr_main_set == HAL_ANT_DIV_COMB_LNA2)
475220593Sadrian				div_ant_conf.alt_lna_conf =
476239890Sadrian						HAL_ANT_DIV_COMB_LNA1;
477239890Sadrian			else if (curr_main_set == HAL_ANT_DIV_COMB_LNA1)
478220593Sadrian				div_ant_conf.alt_lna_conf =
479239890Sadrian						HAL_ANT_DIV_COMB_LNA2;
480220593Sadrian
481220593Sadrian			goto div_comb_done;
482220593Sadrian		}
483220593Sadrian
484220593Sadrian		if ((alt_rssi_avg < (main_rssi_avg +
485220593Sadrian		    ATH_ANT_DIV_COMB_LNA1_LNA2_DELTA)))
486220593Sadrian			goto div_comb_done;
487220593Sadrian	}
488220593Sadrian
489220593Sadrian	if (!antcomb->scan_not_start) {
490220593Sadrian		switch (curr_alt_set) {
491239890Sadrian		case HAL_ANT_DIV_COMB_LNA2:
492220593Sadrian			antcomb->rssi_lna2 = alt_rssi_avg;
493220593Sadrian			antcomb->rssi_lna1 = main_rssi_avg;
494220593Sadrian			antcomb->scan = AH_TRUE;
495220593Sadrian			/* set to A+B */
496220593Sadrian			div_ant_conf.main_lna_conf =
497239890Sadrian				HAL_ANT_DIV_COMB_LNA1;
498220593Sadrian			div_ant_conf.alt_lna_conf  =
499239890Sadrian				HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
500220593Sadrian			break;
501239890Sadrian		case HAL_ANT_DIV_COMB_LNA1:
502220593Sadrian			antcomb->rssi_lna1 = alt_rssi_avg;
503220593Sadrian			antcomb->rssi_lna2 = main_rssi_avg;
504220593Sadrian			antcomb->scan = AH_TRUE;
505220593Sadrian			/* set to A+B */
506239890Sadrian			div_ant_conf.main_lna_conf = HAL_ANT_DIV_COMB_LNA2;
507220593Sadrian			div_ant_conf.alt_lna_conf  =
508239890Sadrian				HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
509220593Sadrian			break;
510239890Sadrian		case HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2:
511220593Sadrian			antcomb->rssi_add = alt_rssi_avg;
512220593Sadrian			antcomb->scan = AH_TRUE;
513220593Sadrian			/* set to A-B */
514220593Sadrian			div_ant_conf.alt_lna_conf =
515239890Sadrian				HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
516220593Sadrian			break;
517239890Sadrian		case HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2:
518220593Sadrian			antcomb->rssi_sub = alt_rssi_avg;
519220593Sadrian			antcomb->scan = AH_FALSE;
520220593Sadrian			if (antcomb->rssi_lna2 >
521220593Sadrian			    (antcomb->rssi_lna1 +
522220593Sadrian			    ATH_ANT_DIV_COMB_LNA1_LNA2_SWITCH_DELTA)) {
523220593Sadrian				/* use LNA2 as main LNA */
524220593Sadrian				if ((antcomb->rssi_add > antcomb->rssi_lna1) &&
525220593Sadrian				    (antcomb->rssi_add > antcomb->rssi_sub)) {
526220593Sadrian					/* set to A+B */
527220593Sadrian					div_ant_conf.main_lna_conf =
528239890Sadrian						HAL_ANT_DIV_COMB_LNA2;
529220593Sadrian					div_ant_conf.alt_lna_conf  =
530239890Sadrian						HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
531220593Sadrian				} else if (antcomb->rssi_sub >
532220593Sadrian					   antcomb->rssi_lna1) {
533220593Sadrian					/* set to A-B */
534220593Sadrian					div_ant_conf.main_lna_conf =
535239890Sadrian						HAL_ANT_DIV_COMB_LNA2;
536220593Sadrian					div_ant_conf.alt_lna_conf =
537239890Sadrian						HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
538220593Sadrian				} else {
539220593Sadrian					/* set to LNA1 */
540220593Sadrian					div_ant_conf.main_lna_conf =
541239890Sadrian						HAL_ANT_DIV_COMB_LNA2;
542220593Sadrian					div_ant_conf.alt_lna_conf =
543239890Sadrian						HAL_ANT_DIV_COMB_LNA1;
544220593Sadrian				}
545220593Sadrian			} else {
546220593Sadrian				/* use LNA1 as main LNA */
547220593Sadrian				if ((antcomb->rssi_add > antcomb->rssi_lna2) &&
548220593Sadrian				    (antcomb->rssi_add > antcomb->rssi_sub)) {
549220593Sadrian					/* set to A+B */
550220593Sadrian					div_ant_conf.main_lna_conf =
551239890Sadrian						HAL_ANT_DIV_COMB_LNA1;
552220593Sadrian					div_ant_conf.alt_lna_conf  =
553239890Sadrian						HAL_ANT_DIV_COMB_LNA1_PLUS_LNA2;
554220593Sadrian				} else if (antcomb->rssi_sub >
555220593Sadrian					   antcomb->rssi_lna1) {
556220593Sadrian					/* set to A-B */
557220593Sadrian					div_ant_conf.main_lna_conf =
558239890Sadrian						HAL_ANT_DIV_COMB_LNA1;
559220593Sadrian					div_ant_conf.alt_lna_conf =
560239890Sadrian						HAL_ANT_DIV_COMB_LNA1_MINUS_LNA2;
561220593Sadrian				} else {
562220593Sadrian					/* set to LNA2 */
563220593Sadrian					div_ant_conf.main_lna_conf =
564239890Sadrian						HAL_ANT_DIV_COMB_LNA1;
565220593Sadrian					div_ant_conf.alt_lna_conf =
566239890Sadrian						HAL_ANT_DIV_COMB_LNA2;
567220593Sadrian				}
568220593Sadrian			}
569220593Sadrian			break;
570220593Sadrian		default:
571220593Sadrian			break;
572220593Sadrian		}
573220593Sadrian	} else {
574220593Sadrian		if (!antcomb->alt_good) {
575220593Sadrian			antcomb->scan_not_start = AH_FALSE;
576220593Sadrian			/* Set alt to another LNA */
577239890Sadrian			if (curr_main_set == HAL_ANT_DIV_COMB_LNA2) {
578220593Sadrian				div_ant_conf.main_lna_conf =
579239890Sadrian						HAL_ANT_DIV_COMB_LNA2;
580220593Sadrian				div_ant_conf.alt_lna_conf =
581239890Sadrian						HAL_ANT_DIV_COMB_LNA1;
582239890Sadrian			} else if (curr_main_set == HAL_ANT_DIV_COMB_LNA1) {
583220593Sadrian				div_ant_conf.main_lna_conf =
584239890Sadrian						HAL_ANT_DIV_COMB_LNA1;
585220593Sadrian				div_ant_conf.alt_lna_conf =
586239890Sadrian						HAL_ANT_DIV_COMB_LNA2;
587220593Sadrian			}
588220593Sadrian			goto div_comb_done;
589220593Sadrian		}
590220593Sadrian	}
591220593Sadrian
592220593Sadrian	ath_select_ant_div_from_quick_scan(antcomb, &div_ant_conf,
593220593Sadrian					   main_rssi_avg, alt_rssi_avg,
594220593Sadrian					   alt_ratio);
595220593Sadrian
596220593Sadrian	antcomb->quick_scan_cnt++;
597220593Sadrian
598220593Sadriandiv_comb_done:
599220593Sadrian	ath_ant_div_conf_fast_divbias(&div_ant_conf);
600220593Sadrian
601220593Sadrian	ar9285_antdiv_comb_conf_set(ah, &div_ant_conf);
602220593Sadrian
603221694Sadrian	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: total_pkt_count=%d\n",
604221694Sadrian	   __func__, antcomb->total_pkt_count);
605221694Sadrian
606221694Sadrian	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main_total_rssi=%d\n",
607221694Sadrian	   __func__, antcomb->main_total_rssi);
608221694Sadrian	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: alt_total_rssi=%d\n",
609221694Sadrian	   __func__, antcomb->alt_total_rssi);
610221694Sadrian
611221694Sadrian	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main_rssi_avg=%d\n",
612221694Sadrian	   __func__, main_rssi_avg);
613221694Sadrian	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: alt_alt_rssi_avg=%d\n",
614221694Sadrian	   __func__, alt_rssi_avg);
615221694Sadrian
616221694Sadrian	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main_recv_cnt=%d\n",
617221694Sadrian	   __func__, antcomb->main_recv_cnt);
618221694Sadrian	HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: alt_recv_cnt=%d\n",
619221694Sadrian	   __func__, antcomb->alt_recv_cnt);
620221694Sadrian
621221833Sadrian//	if (curr_alt_set != div_ant_conf.alt_lna_conf)
622220599Sadrian		HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: lna_conf: %x -> %x\n",
623220599Sadrian		    __func__, curr_alt_set, div_ant_conf.alt_lna_conf);
624221833Sadrian//	if (curr_main_set != div_ant_conf.main_lna_conf)
625220599Sadrian		HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: main_lna_conf: %x -> %x\n",
626220599Sadrian		    __func__, curr_main_set, div_ant_conf.main_lna_conf);
627221833Sadrian//	if (curr_bias != div_ant_conf.fast_div_bias)
628220599Sadrian		HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: fast_div_bias: %x -> %x\n",
629220599Sadrian		    __func__, curr_bias, div_ant_conf.fast_div_bias);
630220599Sadrian
631220593Sadrian	antcomb->scan_start_time = ticks;
632220593Sadrian	antcomb->total_pkt_count = 0;
633220593Sadrian	antcomb->main_total_rssi = 0;
634220593Sadrian	antcomb->alt_total_rssi = 0;
635220593Sadrian	antcomb->main_recv_cnt = 0;
636220593Sadrian	antcomb->alt_recv_cnt = 0;
637220593Sadrian}
638221694Sadrian
639221694Sadrian/*
640221694Sadrian * Set the antenna switch to control RX antenna diversity.
641221694Sadrian *
642221694Sadrian * If a fixed configuration is used, the LNA and div bias
643221694Sadrian * settings are fixed and the antenna diversity scanning routine
644221694Sadrian * is disabled.
645221694Sadrian *
646221694Sadrian * If a variable configuration is used, a default is programmed
647221694Sadrian * in and sampling commences per RXed packet.
648221694Sadrian *
649221694Sadrian * Since this is called from ar9285SetBoardValues() to setup
650221694Sadrian * diversity, it means that after a reset or scan, any current
651221694Sadrian * software diversity combining settings will be lost and won't
652221694Sadrian * re-appear until after the first successful sample run.
653221694Sadrian * Please keep this in mind if you're seeing weird performance
654221694Sadrian * that happens to relate to scan/diversity timing.
655221694Sadrian */
656221694SadrianHAL_BOOL
657221694Sadrianar9285SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
658221694Sadrian{
659221694Sadrian	int regVal;
660221694Sadrian	const HAL_EEPROM_v4k *ee = AH_PRIVATE(ah)->ah_eeprom;
661221694Sadrian	const MODAL_EEP4K_HEADER *pModal = &ee->ee_base.modalHeader;
662221694Sadrian	uint8_t ant_div_control1, ant_div_control2;
663221694Sadrian
664221694Sadrian	if (pModal->version < 3) {
665221694Sadrian		HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: not supported\n",
666221694Sadrian	    __func__);
667221694Sadrian		return AH_FALSE;	/* Can't do diversity */
668221694Sadrian	}
669221694Sadrian
670221694Sadrian	/* Store settings */
671221694Sadrian	AH5212(ah)->ah_antControl = settings;
672221694Sadrian	AH5212(ah)->ah_diversity = (settings == HAL_ANT_VARIABLE);
673221694Sadrian
674221694Sadrian	/* XXX don't fiddle if the PHY is in sleep mode or ! chan */
675221694Sadrian
676221694Sadrian	/* Begin setting the relevant registers */
677221694Sadrian
678221694Sadrian	ant_div_control1 = pModal->antdiv_ctl1;
679221694Sadrian	ant_div_control2 = pModal->antdiv_ctl2;
680221694Sadrian
681221694Sadrian	regVal = OS_REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
682221694Sadrian	regVal &= (~(AR_PHY_9285_ANT_DIV_CTL_ALL));
683221694Sadrian
684221694Sadrian	/* enable antenna diversity only if diversityControl == HAL_ANT_VARIABLE */
685221694Sadrian	if (settings == HAL_ANT_VARIABLE)
686221694Sadrian	    regVal |= SM(ant_div_control1, AR_PHY_9285_ANT_DIV_CTL);
687221694Sadrian
688221694Sadrian	if (settings == HAL_ANT_VARIABLE) {
689221694Sadrian	    HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: HAL_ANT_VARIABLE\n",
690221694Sadrian	      __func__);
691221694Sadrian	    regVal |= SM(ant_div_control2, AR_PHY_9285_ANT_DIV_ALT_LNACONF);
692221694Sadrian	    regVal |= SM((ant_div_control2 >> 2), AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
693221694Sadrian	    regVal |= SM((ant_div_control1 >> 1), AR_PHY_9285_ANT_DIV_ALT_GAINTB);
694221694Sadrian	    regVal |= SM((ant_div_control1 >> 2), AR_PHY_9285_ANT_DIV_MAIN_GAINTB);
695221694Sadrian	} else {
696221694Sadrian	    if (settings == HAL_ANT_FIXED_A) {
697221694Sadrian		/* Diversity disabled, RX = LNA1 */
698221694Sadrian		HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: HAL_ANT_FIXED_A\n",
699221694Sadrian		    __func__);
700239890Sadrian		regVal |= SM(HAL_ANT_DIV_COMB_LNA2, AR_PHY_9285_ANT_DIV_ALT_LNACONF);
701239890Sadrian		regVal |= SM(HAL_ANT_DIV_COMB_LNA1, AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
702221694Sadrian		regVal |= SM(AR_PHY_9285_ANT_DIV_GAINTB_0, AR_PHY_9285_ANT_DIV_ALT_GAINTB);
703221694Sadrian		regVal |= SM(AR_PHY_9285_ANT_DIV_GAINTB_1, AR_PHY_9285_ANT_DIV_MAIN_GAINTB);
704221694Sadrian	    }
705221694Sadrian	    else if (settings == HAL_ANT_FIXED_B) {
706221694Sadrian		/* Diversity disabled, RX = LNA2 */
707221694Sadrian		HALDEBUG(ah, HAL_DEBUG_DIVERSITY, "%s: HAL_ANT_FIXED_B\n",
708221694Sadrian		    __func__);
709239890Sadrian		regVal |= SM(HAL_ANT_DIV_COMB_LNA1, AR_PHY_9285_ANT_DIV_ALT_LNACONF);
710239890Sadrian		regVal |= SM(HAL_ANT_DIV_COMB_LNA2, AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
711221694Sadrian		regVal |= SM(AR_PHY_9285_ANT_DIV_GAINTB_1, AR_PHY_9285_ANT_DIV_ALT_GAINTB);
712221694Sadrian		regVal |= SM(AR_PHY_9285_ANT_DIV_GAINTB_0, AR_PHY_9285_ANT_DIV_MAIN_GAINTB);
713221694Sadrian	    }
714221694Sadrian	}
715221694Sadrian
716221694Sadrian	OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal);
717221694Sadrian	regVal = OS_REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
718221694Sadrian	regVal = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
719221694Sadrian	regVal &= (~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
720221694Sadrian	if (settings == HAL_ANT_VARIABLE)
721221694Sadrian	    regVal |= SM((ant_div_control1 >> 3), AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV);
722221694Sadrian
723221694Sadrian	OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, regVal);
724221694Sadrian	regVal = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
725221694Sadrian
726221694Sadrian	/*
727221694Sadrian	 * If Diversity combining is available and the diversity setting
728221694Sadrian	 * is to allow variable diversity, enable it by default.
729221694Sadrian	 *
730221694Sadrian	 * This will be eventually overridden by the software antenna
731221694Sadrian	 * diversity logic.
732221694Sadrian	 *
733221694Sadrian	 * Note that yes, this following section overrides the above
734221694Sadrian	 * settings for the LNA configuration and fast-bias.
735221694Sadrian	 */
736221694Sadrian	if (ar9285_check_div_comb(ah) && AH5212(ah)->ah_diversity == AH_TRUE) {
737221694Sadrian		// If support DivComb, set MAIN to LNA1 and ALT to LNA2 at the first beginning
738221694Sadrian		HALDEBUG(ah, HAL_DEBUG_DIVERSITY,
739221694Sadrian		    "%s: Enable initial settings for combined diversity\n",
740221694Sadrian		    __func__);
741221694Sadrian		regVal = OS_REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
742221694Sadrian		regVal &= (~(AR_PHY_9285_ANT_DIV_MAIN_LNACONF | AR_PHY_9285_ANT_DIV_ALT_LNACONF));
743239890Sadrian		regVal |= (HAL_ANT_DIV_COMB_LNA1 << AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S);
744239890Sadrian		regVal |= (HAL_ANT_DIV_COMB_LNA2 << AR_PHY_9285_ANT_DIV_ALT_LNACONF_S);
745221694Sadrian		regVal &= (~(AR_PHY_9285_FAST_DIV_BIAS));
746221694Sadrian		regVal |= (0 << AR_PHY_9285_FAST_DIV_BIAS_S);
747221694Sadrian		OS_REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regVal);
748221694Sadrian	}
749221694Sadrian
750221694Sadrian	return AH_TRUE;
751221694Sadrian}
752