xref: /titanic_50/usr/src/uts/common/io/rtw/rtwphy.c (revision 9aa73b6813b3fd35e78fcc44fd17535e765e504c)
1a72f7ea6Sql147931 /*
2*9aa73b68SQin Michael Li  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3a72f7ea6Sql147931  * Use is subject to license terms.
4a72f7ea6Sql147931  */
5a72f7ea6Sql147931 /*
6a72f7ea6Sql147931  * Copyright (c) 2004, 2005 David Young.  All rights reserved.
7a72f7ea6Sql147931  *
8a72f7ea6Sql147931  * Programmed for NetBSD by David Young.
9a72f7ea6Sql147931  *
10a72f7ea6Sql147931  * Redistribution and use in source and binary forms, with or without
11a72f7ea6Sql147931  * modification, are permitted provided that the following conditions
12a72f7ea6Sql147931  * are met:
13a72f7ea6Sql147931  * 1. Redistributions of source code must retain the above copyright
14a72f7ea6Sql147931  *    notice, this list of conditions and the following disclaimer.
15a72f7ea6Sql147931  * 2. Redistributions in binary form must reproduce the above copyright
16a72f7ea6Sql147931  *    notice, this list of conditions and the following disclaimer in the
17a72f7ea6Sql147931  *    documentation and/or other materials provided with the distribution.
18a72f7ea6Sql147931  * 3. The name of David Young may not be used to endorse or promote
19a72f7ea6Sql147931  *    products derived from this software without specific prior
20a72f7ea6Sql147931  *    written permission.
21a72f7ea6Sql147931  *
22a72f7ea6Sql147931  * THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY
23a72f7ea6Sql147931  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24a72f7ea6Sql147931  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25a72f7ea6Sql147931  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL David
26a72f7ea6Sql147931  * Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27a72f7ea6Sql147931  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28a72f7ea6Sql147931  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29a72f7ea6Sql147931  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30a72f7ea6Sql147931  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31a72f7ea6Sql147931  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32a72f7ea6Sql147931  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
33a72f7ea6Sql147931  * OF SUCH DAMAGE.
34a72f7ea6Sql147931  */
35a72f7ea6Sql147931 /*
36a72f7ea6Sql147931  * Control the Philips SA2400 RF front-end and the baseband processor
37a72f7ea6Sql147931  * built into the Realtek RTL8180.
38a72f7ea6Sql147931  */
39a72f7ea6Sql147931 #include <sys/types.h>
40*9aa73b68SQin Michael Li #include <sys/sysmacros.h>
41a72f7ea6Sql147931 #include "rtwreg.h"
42a72f7ea6Sql147931 #include "rtwvar.h"
43a72f7ea6Sql147931 #include "max2820reg.h"
44a72f7ea6Sql147931 #include "sa2400reg.h"
45a72f7ea6Sql147931 #include "rtwphyio.h"
46a72f7ea6Sql147931 #include "rtwphy.h"
47a72f7ea6Sql147931 
48a72f7ea6Sql147931 static int rtw_max2820_pwrstate(struct rtw_rf *, enum rtw_pwrstate);
49a72f7ea6Sql147931 static int rtw_sa2400_pwrstate(struct rtw_rf *, enum rtw_pwrstate);
50a72f7ea6Sql147931 
51a72f7ea6Sql147931 static int
rtw_rf_init(struct rtw_rf * rf,uint_t freq,uint8_t opaque_txpower,enum rtw_pwrstate power)52a72f7ea6Sql147931 rtw_rf_init(struct rtw_rf *rf, uint_t freq, uint8_t opaque_txpower,
53a72f7ea6Sql147931     enum rtw_pwrstate power)
54a72f7ea6Sql147931 {
55a72f7ea6Sql147931 	return (*rf->rf_init)(rf, freq, opaque_txpower, power);
56a72f7ea6Sql147931 }
57a72f7ea6Sql147931 
58a72f7ea6Sql147931 static int
rtw_rf_tune(struct rtw_rf * rf,uint_t freq)59a72f7ea6Sql147931 rtw_rf_tune(struct rtw_rf *rf, uint_t freq)
60a72f7ea6Sql147931 {
61a72f7ea6Sql147931 	return (*rf->rf_tune)(rf, freq);
62a72f7ea6Sql147931 }
63a72f7ea6Sql147931 
64a72f7ea6Sql147931 static int
rtw_rf_txpower(struct rtw_rf * rf,uint8_t opaque_txpower)65a72f7ea6Sql147931 rtw_rf_txpower(struct rtw_rf *rf, uint8_t opaque_txpower)
66a72f7ea6Sql147931 {
67a72f7ea6Sql147931 	return (*rf->rf_txpower)(rf, opaque_txpower);
68a72f7ea6Sql147931 }
69a72f7ea6Sql147931 
70a72f7ea6Sql147931 static int
rtw_rfbus_write(struct rtw_rfbus * bus,enum rtw_rfchipid rfchipid,uint_t addr,uint32_t val)71a72f7ea6Sql147931 rtw_rfbus_write(struct rtw_rfbus *bus, enum rtw_rfchipid rfchipid, uint_t addr,
72a72f7ea6Sql147931     uint32_t val)
73a72f7ea6Sql147931 {
74a72f7ea6Sql147931 	return (*bus->b_write)(bus->b_regs, rfchipid, addr, val);
75a72f7ea6Sql147931 }
76a72f7ea6Sql147931 
77a72f7ea6Sql147931 static int
rtw_bbp_preinit(struct rtw_regs * regs,uint_t antatten0,int dflantb,uint_t freq)78a72f7ea6Sql147931 rtw_bbp_preinit(struct rtw_regs *regs, uint_t antatten0, int dflantb,
79a72f7ea6Sql147931     uint_t freq)
80a72f7ea6Sql147931 {
81a72f7ea6Sql147931 	uint_t antatten = antatten0;
82a72f7ea6Sql147931 	if (dflantb)
83a72f7ea6Sql147931 		antatten |= RTW_BBP_ANTATTEN_DFLANTB;
84a72f7ea6Sql147931 	if (freq == 2484) /* channel 14 */
85a72f7ea6Sql147931 		antatten |= RTW_BBP_ANTATTEN_CHAN14;
86a72f7ea6Sql147931 	return (rtw_bbp_write(regs, RTW_BBP_ANTATTEN, antatten));
87a72f7ea6Sql147931 }
88a72f7ea6Sql147931 
89a72f7ea6Sql147931 static int
rtw_bbp_init(struct rtw_regs * regs,struct rtw_bbpset * bb,int antdiv,int dflantb,uint8_t cs_threshold,uint_t freq)90a72f7ea6Sql147931 rtw_bbp_init(struct rtw_regs *regs, struct rtw_bbpset *bb, int antdiv,
91a72f7ea6Sql147931     int dflantb, uint8_t cs_threshold, uint_t freq)
92a72f7ea6Sql147931 {
93a72f7ea6Sql147931 	int rc;
94a72f7ea6Sql147931 	uint32_t sys2, sys3;
95a72f7ea6Sql147931 
96a72f7ea6Sql147931 	sys2 = bb->bb_sys2;
97a72f7ea6Sql147931 	if (antdiv)
98a72f7ea6Sql147931 		sys2 |= RTW_BBP_SYS2_ANTDIV;
99a72f7ea6Sql147931 	sys3 = bb->bb_sys3 |
100a72f7ea6Sql147931 	    LSHIFT(cs_threshold, RTW_BBP_SYS3_CSTHRESH_MASK);
101a72f7ea6Sql147931 
102a72f7ea6Sql147931 #define	RTW_BBP_WRITE_OR_RETURN(reg, val) \
103a72f7ea6Sql147931 	if ((rc = rtw_bbp_write(regs, reg, val)) != 0) \
104a72f7ea6Sql147931 		return (rc);
105a72f7ea6Sql147931 
106a72f7ea6Sql147931 	RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS1,		bb->bb_sys1);
107a72f7ea6Sql147931 	RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TXAGC,		bb->bb_txagc);
108a72f7ea6Sql147931 	RTW_BBP_WRITE_OR_RETURN(RTW_BBP_LNADET,		bb->bb_lnadet);
109a72f7ea6Sql147931 	RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCINI,	bb->bb_ifagcini);
110a72f7ea6Sql147931 	RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCLIMIT,	bb->bb_ifagclimit);
111a72f7ea6Sql147931 	RTW_BBP_WRITE_OR_RETURN(RTW_BBP_IFAGCDET,	bb->bb_ifagcdet);
112a72f7ea6Sql147931 
113a72f7ea6Sql147931 	if ((rc = rtw_bbp_preinit(regs, bb->bb_antatten, dflantb, freq)) != 0)
114a72f7ea6Sql147931 		return (rc);
115a72f7ea6Sql147931 
116a72f7ea6Sql147931 	RTW_BBP_WRITE_OR_RETURN(RTW_BBP_TRL,		bb->bb_trl);
117a72f7ea6Sql147931 	RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS2,		sys2);
118a72f7ea6Sql147931 	RTW_BBP_WRITE_OR_RETURN(RTW_BBP_SYS3,		sys3);
119a72f7ea6Sql147931 	RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHESTLIM,	bb->bb_chestlim);
120a72f7ea6Sql147931 	RTW_BBP_WRITE_OR_RETURN(RTW_BBP_CHSQLIM,	bb->bb_chsqlim);
121a72f7ea6Sql147931 	return (0);
122a72f7ea6Sql147931 }
123a72f7ea6Sql147931 
124a72f7ea6Sql147931 static int
rtw_sa2400_txpower(struct rtw_rf * rf,uint8_t opaque_txpower)125a72f7ea6Sql147931 rtw_sa2400_txpower(struct rtw_rf *rf, uint8_t opaque_txpower)
126a72f7ea6Sql147931 {
127a72f7ea6Sql147931 	struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf;
128a72f7ea6Sql147931 	struct rtw_rfbus *bus = &sa->sa_bus;
129a72f7ea6Sql147931 
130a72f7ea6Sql147931 	return (rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_TX,
131a72f7ea6Sql147931 	    opaque_txpower));
132a72f7ea6Sql147931 }
133a72f7ea6Sql147931 
134a72f7ea6Sql147931 #ifdef _RTW_FUTURE_DEBUG_
135a72f7ea6Sql147931 /*
136a72f7ea6Sql147931  * make sure we're using the same settings as the reference driver
137a72f7ea6Sql147931  */
138a72f7ea6Sql147931 static void
verify_syna(uint_t freq,uint32_t val)139a72f7ea6Sql147931 verify_syna(uint_t freq, uint32_t val)
140a72f7ea6Sql147931 {
141a72f7ea6Sql147931 	uint32_t expected_val = ~val;
142a72f7ea6Sql147931 
143a72f7ea6Sql147931 	switch (freq) {
144a72f7ea6Sql147931 	case 2412:
145a72f7ea6Sql147931 		expected_val = 0x0000096c; /* ch 1 */
146a72f7ea6Sql147931 		break;
147a72f7ea6Sql147931 	case 2417:
148a72f7ea6Sql147931 		expected_val = 0x00080970; /* ch 2 */
149a72f7ea6Sql147931 		break;
150a72f7ea6Sql147931 	case 2422:
151a72f7ea6Sql147931 		expected_val = 0x00100974; /* ch 3 */
152a72f7ea6Sql147931 		break;
153a72f7ea6Sql147931 	case 2427:
154a72f7ea6Sql147931 		expected_val = 0x00180978; /* ch 4 */
155a72f7ea6Sql147931 		break;
156a72f7ea6Sql147931 	case 2432:
157a72f7ea6Sql147931 		expected_val = 0x00000980; /* ch 5 */
158a72f7ea6Sql147931 		break;
159a72f7ea6Sql147931 	case 2437:
160a72f7ea6Sql147931 		expected_val = 0x00080984; /* ch 6 */
161a72f7ea6Sql147931 		break;
162a72f7ea6Sql147931 	case 2442:
163a72f7ea6Sql147931 		expected_val = 0x00100988; /* ch 7 */
164a72f7ea6Sql147931 		break;
165a72f7ea6Sql147931 	case 2447:
166a72f7ea6Sql147931 		expected_val = 0x0018098c; /* ch 8 */
167a72f7ea6Sql147931 		break;
168a72f7ea6Sql147931 	case 2452:
169a72f7ea6Sql147931 		expected_val = 0x00000994; /* ch 9 */
170a72f7ea6Sql147931 		break;
171a72f7ea6Sql147931 	case 2457:
172a72f7ea6Sql147931 		expected_val = 0x00080998; /* ch 10 */
173a72f7ea6Sql147931 		break;
174a72f7ea6Sql147931 	case 2462:
175a72f7ea6Sql147931 		expected_val = 0x0010099c; /* ch 11 */
176a72f7ea6Sql147931 		break;
177a72f7ea6Sql147931 	case 2467:
178a72f7ea6Sql147931 		expected_val = 0x001809a0; /* ch 12 */
179a72f7ea6Sql147931 		break;
180a72f7ea6Sql147931 	case 2472:
181a72f7ea6Sql147931 		expected_val = 0x000009a8; /* ch 13 */
182a72f7ea6Sql147931 		break;
183a72f7ea6Sql147931 	case 2484:
184a72f7ea6Sql147931 		expected_val = 0x000009b4; /* ch 14 */
185a72f7ea6Sql147931 		break;
186a72f7ea6Sql147931 	}
187a72f7ea6Sql147931 }
188a72f7ea6Sql147931 #endif /* _RTW_FUTURE_DEBUG_ */
189a72f7ea6Sql147931 
190a72f7ea6Sql147931 /* freq is in MHz */
191a72f7ea6Sql147931 static int
rtw_sa2400_tune(struct rtw_rf * rf,uint_t freq)192a72f7ea6Sql147931 rtw_sa2400_tune(struct rtw_rf *rf, uint_t freq)
193a72f7ea6Sql147931 {
194a72f7ea6Sql147931 	struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf;
195a72f7ea6Sql147931 	struct rtw_rfbus *bus = &sa->sa_bus;
196a72f7ea6Sql147931 	int rc;
197a72f7ea6Sql147931 	uint32_t syna, synb, sync;
198a72f7ea6Sql147931 
199a72f7ea6Sql147931 	/*
200a72f7ea6Sql147931 	 * XO = 44MHz, R = 11, hence N is in units of XO / R = 4MHz.
201a72f7ea6Sql147931 	 *
202a72f7ea6Sql147931 	 * The channel spacing (5MHz) is not divisible by 4MHz, so
203a72f7ea6Sql147931 	 * we set the fractional part of N to compensate.
204a72f7ea6Sql147931 	 */
205a72f7ea6Sql147931 	int n = freq / 4, nf = (freq % 4) * 2;
206a72f7ea6Sql147931 
207a72f7ea6Sql147931 	syna = LSHIFT(nf, SA2400_SYNA_NF_MASK) | LSHIFT(n, SA2400_SYNA_N_MASK);
208a72f7ea6Sql147931 	/* verify_syna(freq, syna); */
209a72f7ea6Sql147931 
210a72f7ea6Sql147931 	/*
211a72f7ea6Sql147931 	 * Divide the 44MHz crystal down to 4MHz. Set the fractional
212a72f7ea6Sql147931 	 * compensation charge pump value to agree with the fractional
213a72f7ea6Sql147931 	 * modulus.
214a72f7ea6Sql147931 	 */
215a72f7ea6Sql147931 	synb = LSHIFT(11, SA2400_SYNB_R_MASK) | SA2400_SYNB_L_NORMAL |
216a72f7ea6Sql147931 	    SA2400_SYNB_ON | SA2400_SYNB_ONE |
217a72f7ea6Sql147931 	    LSHIFT(80, SA2400_SYNB_FC_MASK); /* agrees w/ SA2400_SYNA_FM = 0 */
218a72f7ea6Sql147931 
219a72f7ea6Sql147931 	sync = SA2400_SYNC_CP_NORMAL;
220a72f7ea6Sql147931 
221a72f7ea6Sql147931 	if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNA,
222a72f7ea6Sql147931 	    syna)) != 0)
223a72f7ea6Sql147931 		return (rc);
224a72f7ea6Sql147931 	if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNB,
225a72f7ea6Sql147931 	    synb)) != 0)
226a72f7ea6Sql147931 		return (rc);
227a72f7ea6Sql147931 	if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYNC,
228a72f7ea6Sql147931 	    sync)) != 0)
229a72f7ea6Sql147931 		return (rc);
230a72f7ea6Sql147931 	return (rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_SYND, 0x0));
231a72f7ea6Sql147931 }
232a72f7ea6Sql147931 
233a72f7ea6Sql147931 static int
rtw_sa2400_pwrstate(struct rtw_rf * rf,enum rtw_pwrstate power)234a72f7ea6Sql147931 rtw_sa2400_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power)
235a72f7ea6Sql147931 {
236a72f7ea6Sql147931 	struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf;
237a72f7ea6Sql147931 	struct rtw_rfbus *bus = &sa->sa_bus;
238a72f7ea6Sql147931 	uint32_t opmode;
239a72f7ea6Sql147931 	opmode = SA2400_OPMODE_DEFAULTS;
240a72f7ea6Sql147931 	switch (power) {
241a72f7ea6Sql147931 	case RTW_ON:
242a72f7ea6Sql147931 		opmode |= SA2400_OPMODE_MODE_TXRX;
243a72f7ea6Sql147931 		break;
244a72f7ea6Sql147931 	case RTW_SLEEP:
245a72f7ea6Sql147931 		opmode |= SA2400_OPMODE_MODE_WAIT;
246a72f7ea6Sql147931 		break;
247a72f7ea6Sql147931 	case RTW_OFF:
248a72f7ea6Sql147931 		opmode |= SA2400_OPMODE_MODE_SLEEP;
249a72f7ea6Sql147931 		break;
250a72f7ea6Sql147931 	}
251a72f7ea6Sql147931 
252a72f7ea6Sql147931 	if (sa->sa_digphy)
253a72f7ea6Sql147931 		opmode |= SA2400_OPMODE_DIGIN;
254a72f7ea6Sql147931 
255a72f7ea6Sql147931 	return (rtw_rfbus_write(bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE,
256a72f7ea6Sql147931 	    opmode));
257a72f7ea6Sql147931 }
258a72f7ea6Sql147931 
259a72f7ea6Sql147931 static int
rtw_sa2400_manrx_init(struct rtw_sa2400 * sa)260a72f7ea6Sql147931 rtw_sa2400_manrx_init(struct rtw_sa2400 *sa)
261a72f7ea6Sql147931 {
262a72f7ea6Sql147931 	uint32_t manrx;
263a72f7ea6Sql147931 
264a72f7ea6Sql147931 	/*
265a72f7ea6Sql147931 	 * we are not supposed to be in RXMGC mode when we do
266a72f7ea6Sql147931 	 * this?
267a72f7ea6Sql147931 	 */
268a72f7ea6Sql147931 	manrx = SA2400_MANRX_AHSN;
269a72f7ea6Sql147931 	manrx |= SA2400_MANRX_TEN;
270a72f7ea6Sql147931 	manrx |= LSHIFT(1023, SA2400_MANRX_RXGAIN_MASK);
271a72f7ea6Sql147931 
272a72f7ea6Sql147931 	return (rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_MANRX,
273a72f7ea6Sql147931 	    manrx));
274a72f7ea6Sql147931 }
275a72f7ea6Sql147931 
276a72f7ea6Sql147931 static int
rtw_sa2400_vcocal_start(struct rtw_sa2400 * sa,int start)277a72f7ea6Sql147931 rtw_sa2400_vcocal_start(struct rtw_sa2400 *sa, int start)
278a72f7ea6Sql147931 {
279a72f7ea6Sql147931 	uint32_t opmode;
280a72f7ea6Sql147931 
281a72f7ea6Sql147931 	opmode = SA2400_OPMODE_DEFAULTS;
282a72f7ea6Sql147931 	if (start)
283a72f7ea6Sql147931 		opmode |= SA2400_OPMODE_MODE_VCOCALIB;
284a72f7ea6Sql147931 	else
285a72f7ea6Sql147931 		opmode |= SA2400_OPMODE_MODE_SLEEP;
286a72f7ea6Sql147931 
287a72f7ea6Sql147931 	if (sa->sa_digphy)
288a72f7ea6Sql147931 		opmode |= SA2400_OPMODE_DIGIN;
289a72f7ea6Sql147931 
290a72f7ea6Sql147931 	return (rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS,
291a72f7ea6Sql147931 	    SA2400_OPMODE, opmode));
292a72f7ea6Sql147931 }
293a72f7ea6Sql147931 
294a72f7ea6Sql147931 static int
rtw_sa2400_vco_calibration(struct rtw_sa2400 * sa)295a72f7ea6Sql147931 rtw_sa2400_vco_calibration(struct rtw_sa2400 *sa)
296a72f7ea6Sql147931 {
297a72f7ea6Sql147931 	int rc;
298a72f7ea6Sql147931 	/*
299a72f7ea6Sql147931 	 * calibrate VCO
300a72f7ea6Sql147931 	 */
301a72f7ea6Sql147931 	if ((rc = rtw_sa2400_vcocal_start(sa, 1)) != 0)
302a72f7ea6Sql147931 		return (rc);
303a72f7ea6Sql147931 	DELAY(2200);	/* 2.2 milliseconds */
304a72f7ea6Sql147931 	/*
305a72f7ea6Sql147931 	 * XXX superfluous: SA2400 automatically entered SLEEP mode.
306a72f7ea6Sql147931 	 */
307a72f7ea6Sql147931 	return (rtw_sa2400_vcocal_start(sa, 0));
308a72f7ea6Sql147931 }
309a72f7ea6Sql147931 
310a72f7ea6Sql147931 static int
rtw_sa2400_filter_calibration(struct rtw_sa2400 * sa)311a72f7ea6Sql147931 rtw_sa2400_filter_calibration(struct rtw_sa2400 *sa)
312a72f7ea6Sql147931 {
313a72f7ea6Sql147931 	uint32_t opmode;
314a72f7ea6Sql147931 
315a72f7ea6Sql147931 	opmode = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_FCALIB;
316a72f7ea6Sql147931 	if (sa->sa_digphy)
317a72f7ea6Sql147931 		opmode |= SA2400_OPMODE_DIGIN;
318a72f7ea6Sql147931 
319a72f7ea6Sql147931 	return (rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS,
320a72f7ea6Sql147931 	    SA2400_OPMODE, opmode));
321a72f7ea6Sql147931 }
322a72f7ea6Sql147931 
323a72f7ea6Sql147931 static int
rtw_sa2400_dc_calibration(struct rtw_sa2400 * sa)324a72f7ea6Sql147931 rtw_sa2400_dc_calibration(struct rtw_sa2400 *sa)
325a72f7ea6Sql147931 {
326a72f7ea6Sql147931 	struct rtw_rf *rf = &sa->sa_rf;
327a72f7ea6Sql147931 	int rc;
328a72f7ea6Sql147931 	uint32_t dccal;
329a72f7ea6Sql147931 
330a72f7ea6Sql147931 	(*rf->rf_continuous_tx_cb)(rf->rf_continuous_tx_arg, 1);
331a72f7ea6Sql147931 
332a72f7ea6Sql147931 	dccal = SA2400_OPMODE_DEFAULTS | SA2400_OPMODE_MODE_TXRX;
333a72f7ea6Sql147931 
334a72f7ea6Sql147931 	rc = rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE,
335a72f7ea6Sql147931 	    dccal);
336a72f7ea6Sql147931 	if (rc != 0)
337a72f7ea6Sql147931 		return (rc);
338a72f7ea6Sql147931 
339a72f7ea6Sql147931 	DELAY(5); /* DCALIB after being in Tx mode for 5 microseconds */
340a72f7ea6Sql147931 
341a72f7ea6Sql147931 	dccal &= ~SA2400_OPMODE_MODE_MASK;
342a72f7ea6Sql147931 	dccal |= SA2400_OPMODE_MODE_DCALIB;
343a72f7ea6Sql147931 
344a72f7ea6Sql147931 	rc = rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_OPMODE,
345a72f7ea6Sql147931 	    dccal);
346a72f7ea6Sql147931 	if (rc != 0)
347a72f7ea6Sql147931 		return (rc);
348a72f7ea6Sql147931 	DELAY(20); /* calibration takes at most 20 microseconds */
349a72f7ea6Sql147931 
350a72f7ea6Sql147931 	(*rf->rf_continuous_tx_cb)(rf->rf_continuous_tx_arg, 0);
351a72f7ea6Sql147931 
352a72f7ea6Sql147931 	return (0);
353a72f7ea6Sql147931 }
354a72f7ea6Sql147931 
355a72f7ea6Sql147931 static int
rtw_sa2400_agc_init(struct rtw_sa2400 * sa)356a72f7ea6Sql147931 rtw_sa2400_agc_init(struct rtw_sa2400 *sa)
357a72f7ea6Sql147931 {
358a72f7ea6Sql147931 	uint32_t agc;
359a72f7ea6Sql147931 
360a72f7ea6Sql147931 	agc = LSHIFT(25, SA2400_AGC_MAXGAIN_MASK);
361a72f7ea6Sql147931 	agc |= LSHIFT(7, SA2400_AGC_BBPDELAY_MASK);
362a72f7ea6Sql147931 	agc |= LSHIFT(15, SA2400_AGC_LNADELAY_MASK);
363a72f7ea6Sql147931 	agc |= LSHIFT(27, SA2400_AGC_RXONDELAY_MASK);
364a72f7ea6Sql147931 
365a72f7ea6Sql147931 	return (rtw_rfbus_write(&sa->sa_bus, RTW_RFCHIPID_PHILIPS, SA2400_AGC,
366a72f7ea6Sql147931 	    agc));
367a72f7ea6Sql147931 }
368a72f7ea6Sql147931 
369a72f7ea6Sql147931 static void
rtw_sa2400_destroy(struct rtw_rf * rf)370a72f7ea6Sql147931 rtw_sa2400_destroy(struct rtw_rf *rf)
371a72f7ea6Sql147931 {
372a72f7ea6Sql147931 	struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf;
373a72f7ea6Sql147931 	kmem_free(sa, sizeof (*sa));
374a72f7ea6Sql147931 }
375a72f7ea6Sql147931 
376a72f7ea6Sql147931 static int
rtw_sa2400_calibrate(struct rtw_rf * rf,uint_t freq)377a72f7ea6Sql147931 rtw_sa2400_calibrate(struct rtw_rf *rf, uint_t freq)
378a72f7ea6Sql147931 {
379a72f7ea6Sql147931 	struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf;
380a72f7ea6Sql147931 	int i, rc;
381a72f7ea6Sql147931 
382a72f7ea6Sql147931 	/*
383a72f7ea6Sql147931 	 * XXX reference driver calibrates VCO twice. Is it a bug?
384a72f7ea6Sql147931 	 */
385a72f7ea6Sql147931 	for (i = 0; i < 2; i++) {
386a72f7ea6Sql147931 		if ((rc = rtw_sa2400_vco_calibration(sa)) != 0)
387a72f7ea6Sql147931 			return (rc);
388a72f7ea6Sql147931 	}
389a72f7ea6Sql147931 	/*
390a72f7ea6Sql147931 	 * VCO calibration erases synthesizer registers, so re-tune
391a72f7ea6Sql147931 	 */
392a72f7ea6Sql147931 	if ((rc = rtw_sa2400_tune(rf, freq)) != 0)
393a72f7ea6Sql147931 		return (rc);
394a72f7ea6Sql147931 	if ((rc = rtw_sa2400_filter_calibration(sa)) != 0)
395a72f7ea6Sql147931 		return (rc);
396a72f7ea6Sql147931 	/*
397a72f7ea6Sql147931 	 * analog PHY needs DC calibration
398a72f7ea6Sql147931 	 */
399a72f7ea6Sql147931 	if (!sa->sa_digphy)
400a72f7ea6Sql147931 		return (rtw_sa2400_dc_calibration(sa));
401a72f7ea6Sql147931 	return (0);
402a72f7ea6Sql147931 }
403a72f7ea6Sql147931 
404a72f7ea6Sql147931 static int
rtw_sa2400_init(struct rtw_rf * rf,uint_t freq,uint8_t opaque_txpower,enum rtw_pwrstate power)405a72f7ea6Sql147931 rtw_sa2400_init(struct rtw_rf *rf, uint_t freq, uint8_t opaque_txpower,
406a72f7ea6Sql147931     enum rtw_pwrstate power)
407a72f7ea6Sql147931 {
408a72f7ea6Sql147931 	struct rtw_sa2400 *sa = (struct rtw_sa2400 *)rf;
409a72f7ea6Sql147931 	int rc;
410a72f7ea6Sql147931 
411a72f7ea6Sql147931 	if ((rc = rtw_sa2400_txpower(rf, opaque_txpower)) != 0)
412a72f7ea6Sql147931 		return (rc);
413a72f7ea6Sql147931 
414a72f7ea6Sql147931 	/*
415a72f7ea6Sql147931 	 * skip configuration if it's time to sleep or to power-down.
416a72f7ea6Sql147931 	 */
417a72f7ea6Sql147931 	if (power == RTW_SLEEP || power == RTW_OFF)
418a72f7ea6Sql147931 		return (rtw_sa2400_pwrstate(rf, power));
419a72f7ea6Sql147931 
420a72f7ea6Sql147931 	/*
421a72f7ea6Sql147931 	 * go to sleep for configuration
422a72f7ea6Sql147931 	 */
423a72f7ea6Sql147931 	if ((rc = rtw_sa2400_pwrstate(rf, RTW_SLEEP)) != 0)
424a72f7ea6Sql147931 		return (rc);
425a72f7ea6Sql147931 
426a72f7ea6Sql147931 	if ((rc = rtw_sa2400_tune(rf, freq)) != 0)
427a72f7ea6Sql147931 		return (rc);
428a72f7ea6Sql147931 	if ((rc = rtw_sa2400_agc_init(sa)) != 0)
429a72f7ea6Sql147931 		return (rc);
430a72f7ea6Sql147931 	if ((rc = rtw_sa2400_manrx_init(sa)) != 0)
431a72f7ea6Sql147931 		return (rc);
432a72f7ea6Sql147931 	if ((rc = rtw_sa2400_calibrate(rf, freq)) != 0)
433a72f7ea6Sql147931 		return (rc);
434a72f7ea6Sql147931 
435a72f7ea6Sql147931 	/*
436a72f7ea6Sql147931 	 * enter Tx/Rx mode
437a72f7ea6Sql147931 	 */
438a72f7ea6Sql147931 	return (rtw_sa2400_pwrstate(rf, power));
439a72f7ea6Sql147931 }
440a72f7ea6Sql147931 
441a72f7ea6Sql147931 struct rtw_rf *
rtw_sa2400_create(struct rtw_regs * regs,rtw_rf_write_t rf_write,int digphy)442a72f7ea6Sql147931 rtw_sa2400_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, int digphy)
443a72f7ea6Sql147931 {
444a72f7ea6Sql147931 	struct rtw_sa2400 *sa;
445a72f7ea6Sql147931 	struct rtw_rfbus *bus;
446a72f7ea6Sql147931 	struct rtw_rf *rf;
447a72f7ea6Sql147931 	struct rtw_bbpset *bb;
448a72f7ea6Sql147931 
449a72f7ea6Sql147931 	sa = (struct rtw_sa2400 *)kmem_zalloc(sizeof (*sa), KM_SLEEP);
450a72f7ea6Sql147931 	if (sa == NULL)
451a72f7ea6Sql147931 		return (NULL);
452a72f7ea6Sql147931 
453a72f7ea6Sql147931 	sa->sa_digphy = digphy;
454a72f7ea6Sql147931 
455a72f7ea6Sql147931 	rf = &sa->sa_rf;
456a72f7ea6Sql147931 	bus = &sa->sa_bus;
457a72f7ea6Sql147931 
458a72f7ea6Sql147931 	rf->rf_init = rtw_sa2400_init;
459a72f7ea6Sql147931 	rf->rf_destroy = rtw_sa2400_destroy;
460a72f7ea6Sql147931 	rf->rf_txpower = rtw_sa2400_txpower;
461a72f7ea6Sql147931 	rf->rf_tune = rtw_sa2400_tune;
462a72f7ea6Sql147931 	rf->rf_pwrstate = rtw_sa2400_pwrstate;
463a72f7ea6Sql147931 	bb = &rf->rf_bbpset;
464a72f7ea6Sql147931 
465a72f7ea6Sql147931 	/*
466a72f7ea6Sql147931 	 * XXX magic
467a72f7ea6Sql147931 	 */
468a72f7ea6Sql147931 	bb->bb_antatten = RTW_BBP_ANTATTEN_PHILIPS_MAGIC;
469a72f7ea6Sql147931 	bb->bb_chestlim =	0x00;
470a72f7ea6Sql147931 	bb->bb_chsqlim =	0xa0;
471a72f7ea6Sql147931 	bb->bb_ifagcdet =	0x64;
472a72f7ea6Sql147931 	bb->bb_ifagcini =	0x90;
473a72f7ea6Sql147931 	bb->bb_ifagclimit =	0x1a;
474a72f7ea6Sql147931 	bb->bb_lnadet =		0xe0;
475a72f7ea6Sql147931 	bb->bb_sys1 =		0x98;
476a72f7ea6Sql147931 	bb->bb_sys2 =		0x47;
477a72f7ea6Sql147931 	bb->bb_sys3 =		0x90;
478a72f7ea6Sql147931 	bb->bb_trl =		0x88;
479a72f7ea6Sql147931 	bb->bb_txagc =		0x38;
480a72f7ea6Sql147931 
481a72f7ea6Sql147931 	bus->b_regs = regs;
482a72f7ea6Sql147931 	bus->b_write = rf_write;
483a72f7ea6Sql147931 
484a72f7ea6Sql147931 	return (&sa->sa_rf);
485a72f7ea6Sql147931 }
486a72f7ea6Sql147931 
487a72f7ea6Sql147931 /*
488a72f7ea6Sql147931  * freq is in MHz
489a72f7ea6Sql147931  */
490a72f7ea6Sql147931 static int
rtw_max2820_tune(struct rtw_rf * rf,uint_t freq)491a72f7ea6Sql147931 rtw_max2820_tune(struct rtw_rf *rf, uint_t freq)
492a72f7ea6Sql147931 {
493a72f7ea6Sql147931 	struct rtw_max2820 *mx = (struct rtw_max2820 *)rf;
494a72f7ea6Sql147931 	struct rtw_rfbus *bus = &mx->mx_bus;
495a72f7ea6Sql147931 
496a72f7ea6Sql147931 	if (freq < 2400 || freq > 2499)
497a72f7ea6Sql147931 		return (-1);
498a72f7ea6Sql147931 
499a72f7ea6Sql147931 	return (rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_CHANNEL,
500a72f7ea6Sql147931 	    LSHIFT(freq - 2400, MAX2820_CHANNEL_CF_MASK)));
501a72f7ea6Sql147931 }
502a72f7ea6Sql147931 
503a72f7ea6Sql147931 static void
rtw_max2820_destroy(struct rtw_rf * rf)504a72f7ea6Sql147931 rtw_max2820_destroy(struct rtw_rf *rf)
505a72f7ea6Sql147931 {
506a72f7ea6Sql147931 	struct rtw_max2820 *mx = (struct rtw_max2820 *)rf;
507a72f7ea6Sql147931 	kmem_free(mx, sizeof (*mx));
508a72f7ea6Sql147931 }
509a72f7ea6Sql147931 
510a72f7ea6Sql147931 /*ARGSUSED*/
511a72f7ea6Sql147931 static int
rtw_max2820_init(struct rtw_rf * rf,uint_t freq,uint8_t opaque_txpower,enum rtw_pwrstate power)512a72f7ea6Sql147931 rtw_max2820_init(struct rtw_rf *rf, uint_t freq, uint8_t opaque_txpower,
513a72f7ea6Sql147931     enum rtw_pwrstate power)
514a72f7ea6Sql147931 {
515a72f7ea6Sql147931 	struct rtw_max2820 *mx = (struct rtw_max2820 *)rf;
516a72f7ea6Sql147931 	struct rtw_rfbus *bus = &mx->mx_bus;
517a72f7ea6Sql147931 	int rc;
518a72f7ea6Sql147931 
519a72f7ea6Sql147931 	if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_TEST,
520a72f7ea6Sql147931 	    MAX2820_TEST_DEFAULT)) != 0)
521a72f7ea6Sql147931 		return (rc);
522a72f7ea6Sql147931 
523a72f7ea6Sql147931 	if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_ENABLE,
524a72f7ea6Sql147931 	    MAX2820_ENABLE_DEFAULT)) != 0)
525a72f7ea6Sql147931 		return (rc);
526a72f7ea6Sql147931 
527a72f7ea6Sql147931 	/*
528a72f7ea6Sql147931 	 * skip configuration if it's time to sleep or to power-down.
529a72f7ea6Sql147931 	 */
530a72f7ea6Sql147931 	if ((rc = rtw_max2820_pwrstate(rf, power)) != 0)
531a72f7ea6Sql147931 		return (rc);
532a72f7ea6Sql147931 	else if (power == RTW_OFF || power == RTW_SLEEP)
533a72f7ea6Sql147931 		return (0);
534a72f7ea6Sql147931 
535a72f7ea6Sql147931 	if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_SYNTH,
536a72f7ea6Sql147931 	    MAX2820_SYNTH_R_44MHZ)) != 0)
537a72f7ea6Sql147931 		return (rc);
538a72f7ea6Sql147931 
539a72f7ea6Sql147931 	if ((rc = rtw_max2820_tune(rf, freq)) != 0)
540a72f7ea6Sql147931 		return (rc);
541a72f7ea6Sql147931 
542a72f7ea6Sql147931 	/*
543a72f7ea6Sql147931 	 * XXX The MAX2820 datasheet indicates that 1C and 2C should not
544a72f7ea6Sql147931 	 * be changed from 7, however, the reference driver sets them
545a72f7ea6Sql147931 	 * to 4 and 1, respectively.
546a72f7ea6Sql147931 	 */
547a72f7ea6Sql147931 	if ((rc = rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_RECEIVE,
548a72f7ea6Sql147931 	    MAX2820_RECEIVE_DL_DEFAULT |
549a72f7ea6Sql147931 	    LSHIFT(4, MAX2820A_RECEIVE_1C_MASK) |
550a72f7ea6Sql147931 	    LSHIFT(1, MAX2820A_RECEIVE_2C_MASK))) != 0)
551a72f7ea6Sql147931 		return (rc);
552a72f7ea6Sql147931 
553a72f7ea6Sql147931 	return (rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM, MAX2820_TRANSMIT,
554a72f7ea6Sql147931 	    MAX2820_TRANSMIT_PA_DEFAULT));
555a72f7ea6Sql147931 }
556a72f7ea6Sql147931 
557a72f7ea6Sql147931 /*ARGSUSED*/
558a72f7ea6Sql147931 static int
rtw_max2820_txpower(struct rtw_rf * rf,uint8_t opaque_txpower)559a72f7ea6Sql147931 rtw_max2820_txpower(struct rtw_rf *rf, uint8_t opaque_txpower)
560a72f7ea6Sql147931 {
561a72f7ea6Sql147931 	/* TBD */
562a72f7ea6Sql147931 	return (0);
563a72f7ea6Sql147931 }
564a72f7ea6Sql147931 
565a72f7ea6Sql147931 static int
rtw_max2820_pwrstate(struct rtw_rf * rf,enum rtw_pwrstate power)566a72f7ea6Sql147931 rtw_max2820_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power)
567a72f7ea6Sql147931 {
568a72f7ea6Sql147931 	uint32_t enable;
569a72f7ea6Sql147931 	struct rtw_max2820 *mx;
570a72f7ea6Sql147931 	struct rtw_rfbus *bus;
571a72f7ea6Sql147931 
572a72f7ea6Sql147931 	mx = (struct rtw_max2820 *)rf;
573a72f7ea6Sql147931 	bus = &mx->mx_bus;
574a72f7ea6Sql147931 
575a72f7ea6Sql147931 	switch (power) {
576a72f7ea6Sql147931 	case RTW_OFF:
577a72f7ea6Sql147931 	case RTW_SLEEP:
578a72f7ea6Sql147931 	default:
579a72f7ea6Sql147931 		enable = 0x0;
580a72f7ea6Sql147931 		break;
581a72f7ea6Sql147931 	case RTW_ON:
582a72f7ea6Sql147931 		enable = MAX2820_ENABLE_DEFAULT;
583a72f7ea6Sql147931 		break;
584a72f7ea6Sql147931 	}
585a72f7ea6Sql147931 	return (rtw_rfbus_write(bus, RTW_RFCHIPID_MAXIM,
586a72f7ea6Sql147931 	    MAX2820_ENABLE, enable));
587a72f7ea6Sql147931 }
588a72f7ea6Sql147931 
589a72f7ea6Sql147931 struct rtw_rf *
rtw_max2820_create(struct rtw_regs * regs,rtw_rf_write_t rf_write,int is_a)590a72f7ea6Sql147931 rtw_max2820_create(struct rtw_regs *regs, rtw_rf_write_t rf_write, int is_a)
591a72f7ea6Sql147931 {
592a72f7ea6Sql147931 	struct rtw_max2820 *mx;
593a72f7ea6Sql147931 	struct rtw_rfbus *bus;
594a72f7ea6Sql147931 	struct rtw_rf *rf;
595a72f7ea6Sql147931 	struct rtw_bbpset *bb;
596a72f7ea6Sql147931 
597a72f7ea6Sql147931 	mx = (struct rtw_max2820 *)kmem_zalloc(sizeof (*mx), KM_SLEEP);
598a72f7ea6Sql147931 	if (mx == NULL)
599a72f7ea6Sql147931 		return (NULL);
600a72f7ea6Sql147931 
601a72f7ea6Sql147931 	mx->mx_is_a = is_a;
602a72f7ea6Sql147931 
603a72f7ea6Sql147931 	rf = &mx->mx_rf;
604a72f7ea6Sql147931 	bus = &mx->mx_bus;
605a72f7ea6Sql147931 
606a72f7ea6Sql147931 	rf->rf_init = rtw_max2820_init;
607a72f7ea6Sql147931 	rf->rf_destroy = rtw_max2820_destroy;
608a72f7ea6Sql147931 	rf->rf_txpower = rtw_max2820_txpower;
609a72f7ea6Sql147931 	rf->rf_tune = rtw_max2820_tune;
610a72f7ea6Sql147931 	rf->rf_pwrstate = rtw_max2820_pwrstate;
611a72f7ea6Sql147931 	bb = &rf->rf_bbpset;
612a72f7ea6Sql147931 
613a72f7ea6Sql147931 	/*
614a72f7ea6Sql147931 	 * XXX magic
615a72f7ea6Sql147931 	 */
616a72f7ea6Sql147931 	bb->bb_antatten = RTW_BBP_ANTATTEN_MAXIM_MAGIC;
617a72f7ea6Sql147931 	bb->bb_chestlim =	0;
618a72f7ea6Sql147931 	bb->bb_chsqlim =	159;
619a72f7ea6Sql147931 	bb->bb_ifagcdet =	100;
620a72f7ea6Sql147931 	bb->bb_ifagcini =	144;
621a72f7ea6Sql147931 	bb->bb_ifagclimit =	26;
622a72f7ea6Sql147931 	bb->bb_lnadet =		248;
623a72f7ea6Sql147931 	bb->bb_sys1 =		136;
624a72f7ea6Sql147931 	bb->bb_sys2 =		71;
625a72f7ea6Sql147931 	bb->bb_sys3 =		155;
626a72f7ea6Sql147931 	bb->bb_trl =		136;
627a72f7ea6Sql147931 	bb->bb_txagc =		8;
628a72f7ea6Sql147931 
629a72f7ea6Sql147931 	bus->b_regs = regs;
630a72f7ea6Sql147931 	bus->b_write = rf_write;
631a72f7ea6Sql147931 
632a72f7ea6Sql147931 	return (&mx->mx_rf);
633a72f7ea6Sql147931 }
634a72f7ea6Sql147931 
635a72f7ea6Sql147931 /*
636a72f7ea6Sql147931  * freq is in MHz
637a72f7ea6Sql147931  */
638a72f7ea6Sql147931 int
rtw_phy_init(struct rtw_regs * regs,struct rtw_rf * rf,uint8_t opaque_txpower,uint8_t cs_threshold,uint_t freq,int antdiv,int dflantb,enum rtw_pwrstate power)639a72f7ea6Sql147931 rtw_phy_init(struct rtw_regs *regs, struct rtw_rf *rf, uint8_t opaque_txpower,
640a72f7ea6Sql147931     uint8_t cs_threshold, uint_t freq, int antdiv, int dflantb,
641a72f7ea6Sql147931     enum rtw_pwrstate power)
642a72f7ea6Sql147931 {
643a72f7ea6Sql147931 	int rc;
644a72f7ea6Sql147931 
645a72f7ea6Sql147931 	/*
646a72f7ea6Sql147931 	 * XXX is this really necessary?
647a72f7ea6Sql147931 	 */
648a72f7ea6Sql147931 	if ((rc = rtw_rf_txpower(rf, opaque_txpower)) != 0)
649a72f7ea6Sql147931 		return (rc);
650a72f7ea6Sql147931 	if ((rc = rtw_bbp_preinit(regs, rf->rf_bbpset.bb_antatten, dflantb,
651a72f7ea6Sql147931 	    freq)) != 0)
652a72f7ea6Sql147931 		return (rc);
653a72f7ea6Sql147931 	if ((rc = rtw_rf_tune(rf, freq)) != 0)
654a72f7ea6Sql147931 		return (rc);
655a72f7ea6Sql147931 	/*
656a72f7ea6Sql147931 	 * initialize RF
657a72f7ea6Sql147931 	 */
658a72f7ea6Sql147931 	if ((rc = rtw_rf_init(rf, freq, opaque_txpower, power)) != 0)
659a72f7ea6Sql147931 		return (rc);
660a72f7ea6Sql147931 #ifdef _RTW_FUTURE_DEBUG_
661a72f7ea6Sql147931 	/* what is this redundant tx power setting here for? */
662a72f7ea6Sql147931 	if ((rc = rtw_rf_txpower(rf, opaque_txpower)) != 0)
663a72f7ea6Sql147931 		return (rc);
664a72f7ea6Sql147931 #endif /* _RTW_FUTURE_DEBUG */
665a72f7ea6Sql147931 	return (rtw_bbp_init(regs, &rf->rf_bbpset, antdiv, dflantb,
666a72f7ea6Sql147931 	    cs_threshold, freq));
667a72f7ea6Sql147931 }
668