xref: /freebsd/sys/dev/bwn/if_bwn_phy_lp.c (revision 640235e2c2ba32947f7c59d168437ffa1280f1e6)
1 /*-
2  * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org>
3  * All rights reserved.
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  *    notice, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #include "opt_bwn.h"
34 #include "opt_wlan.h"
35 
36 /*
37  * The Broadcom Wireless LAN controller driver.
38  */
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
44 #include <sys/module.h>
45 #include <sys/endian.h>
46 #include <sys/errno.h>
47 #include <sys/firmware.h>
48 #include <sys/lock.h>
49 #include <sys/mutex.h>
50 #include <machine/bus.h>
51 #include <machine/resource.h>
52 #include <sys/bus.h>
53 #include <sys/rman.h>
54 #include <sys/socket.h>
55 #include <sys/sockio.h>
56 
57 #include <net/ethernet.h>
58 #include <net/if.h>
59 #include <net/if_var.h>
60 #include <net/if_arp.h>
61 #include <net/if_dl.h>
62 #include <net/if_llc.h>
63 #include <net/if_media.h>
64 #include <net/if_types.h>
65 
66 #include <dev/pci/pcivar.h>
67 #include <dev/pci/pcireg.h>
68 #include <dev/siba/siba_ids.h>
69 #include <dev/siba/sibareg.h>
70 #include <dev/siba/sibavar.h>
71 
72 #include <net80211/ieee80211_var.h>
73 #include <net80211/ieee80211_radiotap.h>
74 #include <net80211/ieee80211_regdomain.h>
75 #include <net80211/ieee80211_phy.h>
76 #include <net80211/ieee80211_ratectl.h>
77 
78 #include <dev/bwn/if_bwnreg.h>
79 #include <dev/bwn/if_bwnvar.h>
80 
81 #include <dev/bwn/if_bwn_debug.h>
82 #include <dev/bwn/if_bwn_misc.h>
83 #include <dev/bwn/if_bwn_util.h>
84 #include <dev/bwn/if_bwn_phy_common.h>
85 #include <dev/bwn/if_bwn_phy_lp.h>
86 
87 static void	bwn_phy_lp_readsprom(struct bwn_mac *);
88 static void	bwn_phy_lp_bbinit(struct bwn_mac *);
89 static void	bwn_phy_lp_txpctl_init(struct bwn_mac *);
90 static void	bwn_phy_lp_calib(struct bwn_mac *);
91 static int	bwn_phy_lp_b2062_switch_channel(struct bwn_mac *, uint8_t);
92 static int	bwn_phy_lp_b2063_switch_channel(struct bwn_mac *, uint8_t);
93 static void	bwn_phy_lp_set_anafilter(struct bwn_mac *, uint8_t);
94 static void	bwn_phy_lp_set_gaintbl(struct bwn_mac *, uint32_t);
95 static void	bwn_phy_lp_digflt_save(struct bwn_mac *);
96 static void	bwn_phy_lp_get_txpctlmode(struct bwn_mac *);
97 static void	bwn_phy_lp_set_txpctlmode(struct bwn_mac *, uint8_t);
98 static void	bwn_phy_lp_bugfix(struct bwn_mac *);
99 static void	bwn_phy_lp_digflt_restore(struct bwn_mac *);
100 static void	bwn_phy_lp_tblinit(struct bwn_mac *);
101 static void	bwn_phy_lp_bbinit_r2(struct bwn_mac *);
102 static void	bwn_phy_lp_bbinit_r01(struct bwn_mac *);
103 static void	bwn_phy_lp_b2062_init(struct bwn_mac *);
104 static void	bwn_phy_lp_b2063_init(struct bwn_mac *);
105 static void	bwn_phy_lp_rxcal_r2(struct bwn_mac *);
106 static void	bwn_phy_lp_rccal_r12(struct bwn_mac *);
107 static void	bwn_phy_lp_set_rccap(struct bwn_mac *);
108 static uint32_t	bwn_phy_lp_roundup(uint32_t, uint32_t, uint8_t);
109 static void	bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *);
110 static void	bwn_phy_lp_b2062_vco_calib(struct bwn_mac *);
111 static void	bwn_tab_write_multi(struct bwn_mac *, uint32_t, int,
112 		    const void *);
113 static void	bwn_tab_read_multi(struct bwn_mac *, uint32_t, int, void *);
114 static struct bwn_txgain
115 		bwn_phy_lp_get_txgain(struct bwn_mac *);
116 static uint8_t	bwn_phy_lp_get_bbmult(struct bwn_mac *);
117 static void	bwn_phy_lp_set_txgain(struct bwn_mac *, struct bwn_txgain *);
118 static void	bwn_phy_lp_set_bbmult(struct bwn_mac *, uint8_t);
119 static void	bwn_phy_lp_set_trsw_over(struct bwn_mac *, uint8_t, uint8_t);
120 static void	bwn_phy_lp_set_rxgain(struct bwn_mac *, uint32_t);
121 static void	bwn_phy_lp_set_deaf(struct bwn_mac *, uint8_t);
122 static int	bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *, uint16_t);
123 static void	bwn_phy_lp_clear_deaf(struct bwn_mac *, uint8_t);
124 static void	bwn_phy_lp_tblinit_r01(struct bwn_mac *);
125 static void	bwn_phy_lp_tblinit_r2(struct bwn_mac *);
126 static void	bwn_phy_lp_tblinit_txgain(struct bwn_mac *);
127 static void	bwn_tab_write(struct bwn_mac *, uint32_t, uint32_t);
128 static void	bwn_phy_lp_b2062_tblinit(struct bwn_mac *);
129 static void	bwn_phy_lp_b2063_tblinit(struct bwn_mac *);
130 static int	bwn_phy_lp_loopback(struct bwn_mac *);
131 static void	bwn_phy_lp_set_rxgain_idx(struct bwn_mac *, uint16_t);
132 static void	bwn_phy_lp_ddfs_turnon(struct bwn_mac *, int, int, int, int,
133 		    int);
134 static uint8_t	bwn_phy_lp_rx_iq_est(struct bwn_mac *, uint16_t, uint8_t,
135 		    struct bwn_phy_lp_iq_est *);
136 static void	bwn_phy_lp_ddfs_turnoff(struct bwn_mac *);
137 static uint32_t	bwn_tab_read(struct bwn_mac *, uint32_t);
138 static void	bwn_phy_lp_set_txgain_dac(struct bwn_mac *, uint16_t);
139 static void	bwn_phy_lp_set_txgain_pa(struct bwn_mac *, uint16_t);
140 static void	bwn_phy_lp_set_txgain_override(struct bwn_mac *);
141 static uint16_t	bwn_phy_lp_get_pa_gain(struct bwn_mac *);
142 static uint8_t	bwn_nbits(int32_t);
143 static void	bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *, int, int,
144 		    struct bwn_txgain_entry *);
145 static void	bwn_phy_lp_gaintbl_write(struct bwn_mac *, int,
146 		    struct bwn_txgain_entry);
147 static void	bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *, int,
148 		    struct bwn_txgain_entry);
149 static void	bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *, int,
150 		    struct bwn_txgain_entry);
151 
152 static const uint8_t bwn_b2063_chantable_data[33][12] = {
153 	{ 0x6f, 0x3c, 0x3c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
154 	{ 0x6f, 0x2c, 0x2c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
155 	{ 0x6f, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
156 	{ 0x6e, 0x1c, 0x1c, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
157 	{ 0x6e, 0xc, 0xc, 0x4, 0x5, 0x5, 0x5, 0x5, 0x77, 0x80, 0x80, 0x70 },
158 	{ 0x6a, 0xc, 0xc, 0, 0x2, 0x5, 0xd, 0xd, 0x77, 0x80, 0x20, 0 },
159 	{ 0x6a, 0xc, 0xc, 0, 0x1, 0x5, 0xd, 0xc, 0x77, 0x80, 0x20, 0 },
160 	{ 0x6a, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x80, 0x20, 0 },
161 	{ 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xc, 0xc, 0x77, 0x70, 0x20, 0 },
162 	{ 0x69, 0xc, 0xc, 0, 0x1, 0x4, 0xb, 0xc, 0x77, 0x70, 0x20, 0 },
163 	{ 0x69, 0xc, 0xc, 0, 0, 0x4, 0xb, 0xb, 0x77, 0x60, 0x20, 0 },
164 	{ 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xb, 0x77, 0x60, 0x20, 0 },
165 	{ 0x69, 0xc, 0xc, 0, 0, 0x3, 0xa, 0xa, 0x77, 0x60, 0x20, 0 },
166 	{ 0x68, 0xc, 0xc, 0, 0, 0x2, 0x9, 0x9, 0x77, 0x60, 0x20, 0 },
167 	{ 0x68, 0xc, 0xc, 0, 0, 0x1, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
168 	{ 0x67, 0xc, 0xc, 0, 0, 0, 0x8, 0x8, 0x77, 0x50, 0x10, 0 },
169 	{ 0x64, 0xc, 0xc, 0, 0, 0, 0x2, 0x1, 0x77, 0x20, 0, 0 },
170 	{ 0x64, 0xc, 0xc, 0, 0, 0, 0x1, 0x1, 0x77, 0x20, 0, 0 },
171 	{ 0x63, 0xc, 0xc, 0, 0, 0, 0x1, 0, 0x77, 0x10, 0, 0 },
172 	{ 0x63, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
173 	{ 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0x10, 0, 0 },
174 	{ 0x62, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
175 	{ 0x61, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
176 	{ 0x60, 0xc, 0xc, 0, 0, 0, 0, 0, 0x77, 0, 0, 0 },
177 	{ 0x6e, 0xc, 0xc, 0, 0x9, 0xe, 0xf, 0xf, 0x77, 0xc0, 0x50, 0 },
178 	{ 0x6e, 0xc, 0xc, 0, 0x9, 0xd, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
179 	{ 0x6e, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xb0, 0x50, 0 },
180 	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xc, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
181 	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xb, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
182 	{ 0x6d, 0xc, 0xc, 0, 0x8, 0xa, 0xf, 0xf, 0x77, 0xa0, 0x40, 0 },
183 	{ 0x6c, 0xc, 0xc, 0, 0x7, 0x9, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
184 	{ 0x6c, 0xc, 0xc, 0, 0x6, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 },
185 	{ 0x6c, 0xc, 0xc, 0, 0x5, 0x8, 0xf, 0xf, 0x77, 0x90, 0x40, 0 }
186 };
187 
188 static const struct bwn_b206x_chan bwn_b2063_chantable[] = {
189 	{ 1, 2412, bwn_b2063_chantable_data[0] },
190 	{ 2, 2417, bwn_b2063_chantable_data[0] },
191 	{ 3, 2422, bwn_b2063_chantable_data[0] },
192 	{ 4, 2427, bwn_b2063_chantable_data[1] },
193 	{ 5, 2432, bwn_b2063_chantable_data[1] },
194 	{ 6, 2437, bwn_b2063_chantable_data[1] },
195 	{ 7, 2442, bwn_b2063_chantable_data[1] },
196 	{ 8, 2447, bwn_b2063_chantable_data[1] },
197 	{ 9, 2452, bwn_b2063_chantable_data[2] },
198 	{ 10, 2457, bwn_b2063_chantable_data[2] },
199 	{ 11, 2462, bwn_b2063_chantable_data[3] },
200 	{ 12, 2467, bwn_b2063_chantable_data[3] },
201 	{ 13, 2472, bwn_b2063_chantable_data[3] },
202 	{ 14, 2484, bwn_b2063_chantable_data[4] },
203 	{ 34, 5170, bwn_b2063_chantable_data[5] },
204 	{ 36, 5180, bwn_b2063_chantable_data[6] },
205 	{ 38, 5190, bwn_b2063_chantable_data[7] },
206 	{ 40, 5200, bwn_b2063_chantable_data[8] },
207 	{ 42, 5210, bwn_b2063_chantable_data[9] },
208 	{ 44, 5220, bwn_b2063_chantable_data[10] },
209 	{ 46, 5230, bwn_b2063_chantable_data[11] },
210 	{ 48, 5240, bwn_b2063_chantable_data[12] },
211 	{ 52, 5260, bwn_b2063_chantable_data[13] },
212 	{ 56, 5280, bwn_b2063_chantable_data[14] },
213 	{ 60, 5300, bwn_b2063_chantable_data[14] },
214 	{ 64, 5320, bwn_b2063_chantable_data[15] },
215 	{ 100, 5500, bwn_b2063_chantable_data[16] },
216 	{ 104, 5520, bwn_b2063_chantable_data[17] },
217 	{ 108, 5540, bwn_b2063_chantable_data[18] },
218 	{ 112, 5560, bwn_b2063_chantable_data[19] },
219 	{ 116, 5580, bwn_b2063_chantable_data[20] },
220 	{ 120, 5600, bwn_b2063_chantable_data[21] },
221 	{ 124, 5620, bwn_b2063_chantable_data[21] },
222 	{ 128, 5640, bwn_b2063_chantable_data[22] },
223 	{ 132, 5660, bwn_b2063_chantable_data[22] },
224 	{ 136, 5680, bwn_b2063_chantable_data[22] },
225 	{ 140, 5700, bwn_b2063_chantable_data[23] },
226 	{ 149, 5745, bwn_b2063_chantable_data[23] },
227 	{ 153, 5765, bwn_b2063_chantable_data[23] },
228 	{ 157, 5785, bwn_b2063_chantable_data[23] },
229 	{ 161, 5805, bwn_b2063_chantable_data[23] },
230 	{ 165, 5825, bwn_b2063_chantable_data[23] },
231 	{ 184, 4920, bwn_b2063_chantable_data[24] },
232 	{ 188, 4940, bwn_b2063_chantable_data[25] },
233 	{ 192, 4960, bwn_b2063_chantable_data[26] },
234 	{ 196, 4980, bwn_b2063_chantable_data[27] },
235 	{ 200, 5000, bwn_b2063_chantable_data[28] },
236 	{ 204, 5020, bwn_b2063_chantable_data[29] },
237 	{ 208, 5040, bwn_b2063_chantable_data[30] },
238 	{ 212, 5060, bwn_b2063_chantable_data[31] },
239 	{ 216, 5080, bwn_b2063_chantable_data[32] }
240 };
241 
242 static const uint8_t bwn_b2062_chantable_data[22][12] = {
243 	{ 0xff, 0xff, 0xb5, 0x1b, 0x24, 0x32, 0x32, 0x88, 0x88, 0, 0, 0 },
244 	{ 0, 0x22, 0x20, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
245 	{ 0, 0x11, 0x10, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
246 	{ 0, 0, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
247 	{ 0, 0x11, 0x20, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
248 	{ 0, 0x11, 0x10, 0x84, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
249 	{ 0, 0x11, 0, 0x83, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
250 	{ 0, 0, 0, 0x63, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
251 	{ 0, 0, 0, 0x62, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
252 	{ 0, 0, 0, 0x30, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
253 	{ 0, 0, 0, 0x20, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
254 	{ 0, 0, 0, 0x10, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
255 	{ 0, 0, 0, 0, 0x3c, 0x77, 0x37, 0xff, 0x88, 0, 0, 0 },
256 	{ 0x55, 0x77, 0x90, 0xf7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
257 	{ 0x44, 0x77, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
258 	{ 0x44, 0x66, 0x80, 0xe7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
259 	{ 0x33, 0x66, 0x70, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
260 	{ 0x22, 0x55, 0x60, 0xd7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
261 	{ 0x22, 0x55, 0x60, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
262 	{ 0x22, 0x44, 0x50, 0xc7, 0x3c, 0x77, 0x35, 0xff, 0xff, 0, 0, 0 },
263 	{ 0x11, 0x44, 0x50, 0xa5, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 },
264 	{ 0, 0x44, 0x40, 0xb6, 0x3c, 0x77, 0x35, 0xff, 0x88, 0, 0, 0 }
265 };
266 
267 static const struct bwn_b206x_chan bwn_b2062_chantable[] = {
268 	{ 1, 2412, bwn_b2062_chantable_data[0] },
269 	{ 2, 2417, bwn_b2062_chantable_data[0] },
270 	{ 3, 2422, bwn_b2062_chantable_data[0] },
271 	{ 4, 2427, bwn_b2062_chantable_data[0] },
272 	{ 5, 2432, bwn_b2062_chantable_data[0] },
273 	{ 6, 2437, bwn_b2062_chantable_data[0] },
274 	{ 7, 2442, bwn_b2062_chantable_data[0] },
275 	{ 8, 2447, bwn_b2062_chantable_data[0] },
276 	{ 9, 2452, bwn_b2062_chantable_data[0] },
277 	{ 10, 2457, bwn_b2062_chantable_data[0] },
278 	{ 11, 2462, bwn_b2062_chantable_data[0] },
279 	{ 12, 2467, bwn_b2062_chantable_data[0] },
280 	{ 13, 2472, bwn_b2062_chantable_data[0] },
281 	{ 14, 2484, bwn_b2062_chantable_data[0] },
282 	{ 34, 5170, bwn_b2062_chantable_data[1] },
283 	{ 38, 5190, bwn_b2062_chantable_data[2] },
284 	{ 42, 5210, bwn_b2062_chantable_data[2] },
285 	{ 46, 5230, bwn_b2062_chantable_data[3] },
286 	{ 36, 5180, bwn_b2062_chantable_data[4] },
287 	{ 40, 5200, bwn_b2062_chantable_data[5] },
288 	{ 44, 5220, bwn_b2062_chantable_data[6] },
289 	{ 48, 5240, bwn_b2062_chantable_data[3] },
290 	{ 52, 5260, bwn_b2062_chantable_data[3] },
291 	{ 56, 5280, bwn_b2062_chantable_data[3] },
292 	{ 60, 5300, bwn_b2062_chantable_data[7] },
293 	{ 64, 5320, bwn_b2062_chantable_data[8] },
294 	{ 100, 5500, bwn_b2062_chantable_data[9] },
295 	{ 104, 5520, bwn_b2062_chantable_data[10] },
296 	{ 108, 5540, bwn_b2062_chantable_data[10] },
297 	{ 112, 5560, bwn_b2062_chantable_data[10] },
298 	{ 116, 5580, bwn_b2062_chantable_data[11] },
299 	{ 120, 5600, bwn_b2062_chantable_data[12] },
300 	{ 124, 5620, bwn_b2062_chantable_data[12] },
301 	{ 128, 5640, bwn_b2062_chantable_data[12] },
302 	{ 132, 5660, bwn_b2062_chantable_data[12] },
303 	{ 136, 5680, bwn_b2062_chantable_data[12] },
304 	{ 140, 5700, bwn_b2062_chantable_data[12] },
305 	{ 149, 5745, bwn_b2062_chantable_data[12] },
306 	{ 153, 5765, bwn_b2062_chantable_data[12] },
307 	{ 157, 5785, bwn_b2062_chantable_data[12] },
308 	{ 161, 5805, bwn_b2062_chantable_data[12] },
309 	{ 165, 5825, bwn_b2062_chantable_data[12] },
310 	{ 184, 4920, bwn_b2062_chantable_data[13] },
311 	{ 188, 4940, bwn_b2062_chantable_data[14] },
312 	{ 192, 4960, bwn_b2062_chantable_data[15] },
313 	{ 196, 4980, bwn_b2062_chantable_data[16] },
314 	{ 200, 5000, bwn_b2062_chantable_data[17] },
315 	{ 204, 5020, bwn_b2062_chantable_data[18] },
316 	{ 208, 5040, bwn_b2062_chantable_data[19] },
317 	{ 212, 5060, bwn_b2062_chantable_data[20] },
318 	{ 216, 5080, bwn_b2062_chantable_data[21] }
319 };
320 
321 /* for LP PHY */
322 static const struct bwn_rxcompco bwn_rxcompco_5354[] = {
323 	{  1, -66, 15 }, {  2, -66, 15 }, {  3, -66, 15 }, {  4, -66, 15 },
324 	{  5, -66, 15 }, {  6, -66, 15 }, {  7, -66, 14 }, {  8, -66, 14 },
325 	{  9, -66, 14 }, { 10, -66, 14 }, { 11, -66, 14 }, { 12, -66, 13 },
326 	{ 13, -66, 13 }, { 14, -66, 13 },
327 };
328 
329 /* for LP PHY */
330 static const struct bwn_rxcompco bwn_rxcompco_r12[] = {
331 	{   1, -64, 13 }, {   2, -64, 13 }, {   3, -64, 13 }, {   4, -64, 13 },
332 	{   5, -64, 12 }, {   6, -64, 12 }, {   7, -64, 12 }, {   8, -64, 12 },
333 	{   9, -64, 12 }, {  10, -64, 11 }, {  11, -64, 11 }, {  12, -64, 11 },
334 	{  13, -64, 11 }, {  14, -64, 10 }, {  34, -62, 24 }, {  38, -62, 24 },
335 	{  42, -62, 24 }, {  46, -62, 23 }, {  36, -62, 24 }, {  40, -62, 24 },
336 	{  44, -62, 23 }, {  48, -62, 23 }, {  52, -62, 23 }, {  56, -62, 22 },
337 	{  60, -62, 22 }, {  64, -62, 22 }, { 100, -62, 16 }, { 104, -62, 16 },
338 	{ 108, -62, 15 }, { 112, -62, 14 }, { 116, -62, 14 }, { 120, -62, 13 },
339 	{ 124, -62, 12 }, { 128, -62, 12 }, { 132, -62, 12 }, { 136, -62, 11 },
340 	{ 140, -62, 10 }, { 149, -61,  9 }, { 153, -61,  9 }, { 157, -61,  9 },
341 	{ 161, -61,  8 }, { 165, -61,  8 }, { 184, -62, 25 }, { 188, -62, 25 },
342 	{ 192, -62, 25 }, { 196, -62, 25 }, { 200, -62, 25 }, { 204, -62, 25 },
343 	{ 208, -62, 25 }, { 212, -62, 25 }, { 216, -62, 26 },
344 };
345 
346 static const struct bwn_rxcompco bwn_rxcompco_r2 = { 0, -64, 0 };
347 
348 static const uint8_t bwn_tab_sigsq_tbl[] = {
349 	0xde, 0xdc, 0xda, 0xd8, 0xd6, 0xd4, 0xd2, 0xcf, 0xcd,
350 	0xca, 0xc7, 0xc4, 0xc1, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
351 	0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0x00,
352 	0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
353 	0xbe, 0xbe, 0xbe, 0xbe, 0xc1, 0xc4, 0xc7, 0xca, 0xcd,
354 	0xcf, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
355 };
356 
357 static const uint8_t bwn_tab_pllfrac_tbl[] = {
358 	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x80,
359 	0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
360 };
361 
362 static const uint16_t bwn_tabl_iqlocal_tbl[] = {
363 	0x0200, 0x0300, 0x0400, 0x0600, 0x0800, 0x0b00, 0x1000, 0x1001, 0x1002,
364 	0x1003, 0x1004, 0x1005, 0x1006, 0x1007, 0x1707, 0x2007, 0x2d07, 0x4007,
365 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
366 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0200, 0x0300, 0x0400, 0x0600,
367 	0x0800, 0x0b00, 0x1000, 0x1001, 0x1002, 0x1003, 0x1004, 0x1005, 0x1006,
368 	0x1007, 0x1707, 0x2007, 0x2d07, 0x4007, 0x0000, 0x0000, 0x0000, 0x0000,
369 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
370 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
371 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
372 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4000, 0x0000, 0x0000,
373 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
374 	0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
375 };
376 
377 void
378 bwn_phy_lp_init_pre(struct bwn_mac *mac)
379 {
380 	struct bwn_phy *phy = &mac->mac_phy;
381 	struct bwn_phy_lp *plp = &phy->phy_lp;
382 
383 	plp->plp_antenna = BWN_ANT_DEFAULT;
384 }
385 
386 int
387 bwn_phy_lp_init(struct bwn_mac *mac)
388 {
389 	static const struct bwn_stxtable tables[] = {
390 		{ 2,  6, 0x3d, 3, 0x01 }, { 1, 12, 0x4c, 1, 0x01 },
391 		{ 1,  8, 0x50, 0, 0x7f }, { 0,  8, 0x44, 0, 0xff },
392 		{ 1,  0, 0x4a, 0, 0xff }, { 0,  4, 0x4d, 0, 0xff },
393 		{ 1,  4, 0x4e, 0, 0xff }, { 0, 12, 0x4f, 0, 0x0f },
394 		{ 1,  0, 0x4f, 4, 0x0f }, { 3,  0, 0x49, 0, 0x0f },
395 		{ 4,  3, 0x46, 4, 0x07 }, { 3, 15, 0x46, 0, 0x01 },
396 		{ 4,  0, 0x46, 1, 0x07 }, { 3,  8, 0x48, 4, 0x07 },
397 		{ 3, 11, 0x48, 0, 0x0f }, { 3,  4, 0x49, 4, 0x0f },
398 		{ 2, 15, 0x45, 0, 0x01 }, { 5, 13, 0x52, 4, 0x07 },
399 		{ 6,  0, 0x52, 7, 0x01 }, { 5,  3, 0x41, 5, 0x07 },
400 		{ 5,  6, 0x41, 0, 0x0f }, { 5, 10, 0x42, 5, 0x07 },
401 		{ 4, 15, 0x42, 0, 0x01 }, { 5,  0, 0x42, 1, 0x07 },
402 		{ 4, 11, 0x43, 4, 0x0f }, { 4,  7, 0x43, 0, 0x0f },
403 		{ 4,  6, 0x45, 1, 0x01 }, { 2,  7, 0x40, 4, 0x0f },
404 		{ 2, 11, 0x40, 0, 0x0f }
405 	};
406 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
407 	struct bwn_softc *sc = mac->mac_sc;
408 	const struct bwn_stxtable *st;
409 	struct ieee80211com *ic = &sc->sc_ic;
410 	int i, error;
411 	uint16_t tmp;
412 
413 	bwn_phy_lp_readsprom(mac);	/* XXX bad place */
414 	bwn_phy_lp_bbinit(mac);
415 
416 	/* initialize RF */
417 	BWN_PHY_SET(mac, BWN_PHY_4WIRECTL, 0x2);
418 	DELAY(1);
419 	BWN_PHY_MASK(mac, BWN_PHY_4WIRECTL, 0xfffd);
420 	DELAY(1);
421 
422 	if (mac->mac_phy.rf_ver == 0x2062)
423 		bwn_phy_lp_b2062_init(mac);
424 	else {
425 		bwn_phy_lp_b2063_init(mac);
426 
427 		/* synchronize stx table. */
428 		for (i = 0; i < N(tables); i++) {
429 			st = &tables[i];
430 			tmp = BWN_RF_READ(mac, st->st_rfaddr);
431 			tmp >>= st->st_rfshift;
432 			tmp <<= st->st_physhift;
433 			BWN_PHY_SETMASK(mac,
434 			    BWN_PHY_OFDM(0xf2 + st->st_phyoffset),
435 			    ~(st->st_mask << st->st_physhift), tmp);
436 		}
437 
438 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf0), 0x5f80);
439 		BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xf1), 0);
440 	}
441 
442 	/* calibrate RC */
443 	if (mac->mac_phy.rev >= 2)
444 		bwn_phy_lp_rxcal_r2(mac);
445 	else if (!plp->plp_rccap) {
446 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
447 			bwn_phy_lp_rccal_r12(mac);
448 	} else
449 		bwn_phy_lp_set_rccap(mac);
450 
451 	error = bwn_phy_lp_switch_channel(mac, 7);
452 	if (error)
453 		device_printf(sc->sc_dev,
454 		    "failed to change channel 7 (%d)\n", error);
455 	bwn_phy_lp_txpctl_init(mac);
456 	bwn_phy_lp_calib(mac);
457 	return (0);
458 }
459 
460 uint16_t
461 bwn_phy_lp_read(struct bwn_mac *mac, uint16_t reg)
462 {
463 
464 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
465 	return (BWN_READ_2(mac, BWN_PHYDATA));
466 }
467 
468 void
469 bwn_phy_lp_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
470 {
471 
472 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
473 	BWN_WRITE_2(mac, BWN_PHYDATA, value);
474 }
475 
476 void
477 bwn_phy_lp_maskset(struct bwn_mac *mac, uint16_t reg, uint16_t mask,
478     uint16_t set)
479 {
480 
481 	BWN_WRITE_2(mac, BWN_PHYCTL, reg);
482 	BWN_WRITE_2(mac, BWN_PHYDATA,
483 	    (BWN_READ_2(mac, BWN_PHYDATA) & mask) | set);
484 }
485 
486 uint16_t
487 bwn_phy_lp_rf_read(struct bwn_mac *mac, uint16_t reg)
488 {
489 
490 	KASSERT(reg != 1, ("unaccessible register %d", reg));
491 	if (mac->mac_phy.rev < 2 && reg != 0x4001)
492 		reg |= 0x100;
493 	if (mac->mac_phy.rev >= 2)
494 		reg |= 0x200;
495 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
496 	return BWN_READ_2(mac, BWN_RFDATALO);
497 }
498 
499 void
500 bwn_phy_lp_rf_write(struct bwn_mac *mac, uint16_t reg, uint16_t value)
501 {
502 
503 	KASSERT(reg != 1, ("unaccessible register %d", reg));
504 	BWN_WRITE_2(mac, BWN_RFCTL, reg);
505 	BWN_WRITE_2(mac, BWN_RFDATALO, value);
506 }
507 
508 void
509 bwn_phy_lp_rf_onoff(struct bwn_mac *mac, int on)
510 {
511 
512 	if (on) {
513 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xe0ff);
514 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2,
515 		    (mac->mac_phy.rev >= 2) ? 0xf7f7 : 0xffe7);
516 		return;
517 	}
518 
519 	if (mac->mac_phy.rev >= 2) {
520 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x83ff);
521 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
522 		BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0x80ff);
523 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xdfff);
524 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0808);
525 		return;
526 	}
527 
528 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xe0ff);
529 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1f00);
530 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfcff);
531 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x0018);
532 }
533 
534 int
535 bwn_phy_lp_switch_channel(struct bwn_mac *mac, uint32_t chan)
536 {
537 	struct bwn_phy *phy = &mac->mac_phy;
538 	struct bwn_phy_lp *plp = &phy->phy_lp;
539 	int error;
540 
541 	if (phy->rf_ver == 0x2063) {
542 		error = bwn_phy_lp_b2063_switch_channel(mac, chan);
543 		if (error)
544 			return (error);
545 	} else {
546 		error = bwn_phy_lp_b2062_switch_channel(mac, chan);
547 		if (error)
548 			return (error);
549 		bwn_phy_lp_set_anafilter(mac, chan);
550 		bwn_phy_lp_set_gaintbl(mac, ieee80211_ieee2mhz(chan, 0));
551 	}
552 
553 	plp->plp_chan = chan;
554 	BWN_WRITE_2(mac, BWN_CHANNEL, chan);
555 	return (0);
556 }
557 
558 uint32_t
559 bwn_phy_lp_get_default_chan(struct bwn_mac *mac)
560 {
561 	struct bwn_softc *sc = mac->mac_sc;
562 	struct ieee80211com *ic = &sc->sc_ic;
563 
564 	return (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? 1 : 36);
565 }
566 
567 void
568 bwn_phy_lp_set_antenna(struct bwn_mac *mac, int antenna)
569 {
570 	struct bwn_phy *phy = &mac->mac_phy;
571 	struct bwn_phy_lp *plp = &phy->phy_lp;
572 
573 	if (phy->rev >= 2 || antenna > BWN_ANTAUTO1)
574 		return;
575 
576 	bwn_hf_write(mac, bwn_hf_read(mac) & ~BWN_HF_UCODE_ANTDIV_HELPER);
577 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffd, antenna & 0x2);
578 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfffe, antenna & 0x1);
579 	bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_UCODE_ANTDIV_HELPER);
580 	plp->plp_antenna = antenna;
581 }
582 
583 void
584 bwn_phy_lp_task_60s(struct bwn_mac *mac)
585 {
586 
587 	bwn_phy_lp_calib(mac);
588 }
589 
590 static void
591 bwn_phy_lp_readsprom(struct bwn_mac *mac)
592 {
593 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
594 	struct bwn_softc *sc = mac->mac_sc;
595 	struct ieee80211com *ic = &sc->sc_ic;
596 
597 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
598 		plp->plp_txisoband_m = siba_sprom_get_tri2g(sc->sc_dev);
599 		plp->plp_bxarch = siba_sprom_get_bxa2g(sc->sc_dev);
600 		plp->plp_rxpwroffset = siba_sprom_get_rxpo2g(sc->sc_dev);
601 		plp->plp_rssivf = siba_sprom_get_rssismf2g(sc->sc_dev);
602 		plp->plp_rssivc = siba_sprom_get_rssismc2g(sc->sc_dev);
603 		plp->plp_rssigs = siba_sprom_get_rssisav2g(sc->sc_dev);
604 		return;
605 	}
606 
607 	plp->plp_txisoband_l = siba_sprom_get_tri5gl(sc->sc_dev);
608 	plp->plp_txisoband_m = siba_sprom_get_tri5g(sc->sc_dev);
609 	plp->plp_txisoband_h = siba_sprom_get_tri5gh(sc->sc_dev);
610 	plp->plp_bxarch = siba_sprom_get_bxa5g(sc->sc_dev);
611 	plp->plp_rxpwroffset = siba_sprom_get_rxpo5g(sc->sc_dev);
612 	plp->plp_rssivf = siba_sprom_get_rssismf5g(sc->sc_dev);
613 	plp->plp_rssivc = siba_sprom_get_rssismc5g(sc->sc_dev);
614 	plp->plp_rssigs = siba_sprom_get_rssisav5g(sc->sc_dev);
615 }
616 
617 static void
618 bwn_phy_lp_bbinit(struct bwn_mac *mac)
619 {
620 
621 	bwn_phy_lp_tblinit(mac);
622 	if (mac->mac_phy.rev >= 2)
623 		bwn_phy_lp_bbinit_r2(mac);
624 	else
625 		bwn_phy_lp_bbinit_r01(mac);
626 }
627 
628 static void
629 bwn_phy_lp_txpctl_init(struct bwn_mac *mac)
630 {
631 	struct bwn_txgain gain_2ghz = { 4, 12, 12, 0 };
632 	struct bwn_txgain gain_5ghz = { 7, 15, 14, 0 };
633 	struct bwn_softc *sc = mac->mac_sc;
634 	struct ieee80211com *ic = &sc->sc_ic;
635 
636 	bwn_phy_lp_set_txgain(mac,
637 	    IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan) ? &gain_2ghz : &gain_5ghz);
638 	bwn_phy_lp_set_bbmult(mac, 150);
639 }
640 
641 static void
642 bwn_phy_lp_calib(struct bwn_mac *mac)
643 {
644 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
645 	struct bwn_softc *sc = mac->mac_sc;
646 	struct ieee80211com *ic = &sc->sc_ic;
647 	const struct bwn_rxcompco *rc = NULL;
648 	struct bwn_txgain ogain;
649 	int i, omode, oafeovr, orf, obbmult;
650 	uint8_t mode, fc = 0;
651 
652 	if (plp->plp_chanfullcal != plp->plp_chan) {
653 		plp->plp_chanfullcal = plp->plp_chan;
654 		fc = 1;
655 	}
656 
657 	bwn_mac_suspend(mac);
658 
659 	/* BlueTooth Coexistance Override */
660 	BWN_WRITE_2(mac, BWN_BTCOEX_CTL, 0x3);
661 	BWN_WRITE_2(mac, BWN_BTCOEX_TXCTL, 0xff);
662 
663 	if (mac->mac_phy.rev >= 2)
664 		bwn_phy_lp_digflt_save(mac);
665 	bwn_phy_lp_get_txpctlmode(mac);
666 	mode = plp->plp_txpctlmode;
667 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
668 	if (mac->mac_phy.rev == 0 && mode != BWN_PHYLP_TXPCTL_OFF)
669 		bwn_phy_lp_bugfix(mac);
670 	if (mac->mac_phy.rev >= 2 && fc == 1) {
671 		bwn_phy_lp_get_txpctlmode(mac);
672 		omode = plp->plp_txpctlmode;
673 		oafeovr = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40;
674 		if (oafeovr)
675 			ogain = bwn_phy_lp_get_txgain(mac);
676 		orf = BWN_PHY_READ(mac, BWN_PHY_RF_PWR_OVERRIDE) & 0xff;
677 		obbmult = bwn_phy_lp_get_bbmult(mac);
678 		bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
679 		if (oafeovr)
680 			bwn_phy_lp_set_txgain(mac, &ogain);
681 		bwn_phy_lp_set_bbmult(mac, obbmult);
682 		bwn_phy_lp_set_txpctlmode(mac, omode);
683 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00, orf);
684 	}
685 	bwn_phy_lp_set_txpctlmode(mac, mode);
686 	if (mac->mac_phy.rev >= 2)
687 		bwn_phy_lp_digflt_restore(mac);
688 
689 	/* do RX IQ Calculation; assumes that noise is true. */
690 	if (siba_get_chipid(sc->sc_dev) == 0x5354) {
691 		for (i = 0; i < N(bwn_rxcompco_5354); i++) {
692 			if (bwn_rxcompco_5354[i].rc_chan == plp->plp_chan)
693 				rc = &bwn_rxcompco_5354[i];
694 		}
695 	} else if (mac->mac_phy.rev >= 2)
696 		rc = &bwn_rxcompco_r2;
697 	else {
698 		for (i = 0; i < N(bwn_rxcompco_r12); i++) {
699 			if (bwn_rxcompco_r12[i].rc_chan == plp->plp_chan)
700 				rc = &bwn_rxcompco_r12[i];
701 		}
702 	}
703 	if (rc == NULL)
704 		goto fail;
705 
706 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, rc->rc_c1);
707 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, rc->rc_c0 << 8);
708 
709 	bwn_phy_lp_set_trsw_over(mac, 1 /* TX */, 0 /* RX */);
710 
711 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
712 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
713 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7, 0);
714 	} else {
715 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
716 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf, 0);
717 	}
718 
719 	bwn_phy_lp_set_rxgain(mac, 0x2d5d);
720 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
721 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
722 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
723 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
724 	bwn_phy_lp_set_deaf(mac, 0);
725 	/* XXX no checking return value? */
726 	(void)bwn_phy_lp_calc_rx_iq_comp(mac, 0xfff0);
727 	bwn_phy_lp_clear_deaf(mac, 0);
728 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffc);
729 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfff7);
730 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffdf);
731 
732 	/* disable RX GAIN override. */
733 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xfffe);
734 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffef);
735 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xffbf);
736 	if (mac->mac_phy.rev >= 2) {
737 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
738 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
739 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfbff);
740 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xe5), 0xfff7);
741 		}
742 	} else {
743 		BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfdff);
744 	}
745 
746 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfffe);
747 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xf7ff);
748 fail:
749 	bwn_mac_enable(mac);
750 }
751 
752 void
753 bwn_phy_lp_switch_analog(struct bwn_mac *mac, int on)
754 {
755 
756 	if (on) {
757 		BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xfff8);
758 		return;
759 	}
760 
761 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVRVAL, 0x0007);
762 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x0007);
763 }
764 
765 static int
766 bwn_phy_lp_b2063_switch_channel(struct bwn_mac *mac, uint8_t chan)
767 {
768 	static const struct bwn_b206x_chan *bc = NULL;
769 	struct bwn_softc *sc = mac->mac_sc;
770 	uint32_t count, freqref, freqvco, freqxtal, val[3], timeout, timeoutref,
771 	    tmp[6];
772 	uint16_t old, scale, tmp16;
773 	int i, div;
774 
775 	for (i = 0; i < N(bwn_b2063_chantable); i++) {
776 		if (bwn_b2063_chantable[i].bc_chan == chan) {
777 			bc = &bwn_b2063_chantable[i];
778 			break;
779 		}
780 	}
781 	if (bc == NULL)
782 		return (EINVAL);
783 
784 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_VCOBUF1, bc->bc_data[0]);
785 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_MIXER2, bc->bc_data[1]);
786 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_BUF2, bc->bc_data[2]);
787 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_RCCR1, bc->bc_data[3]);
788 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_1ST3, bc->bc_data[4]);
789 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND1, bc->bc_data[5]);
790 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND4, bc->bc_data[6]);
791 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_2ND7, bc->bc_data[7]);
792 	BWN_RF_WRITE(mac, BWN_B2063_A_RX_PS6, bc->bc_data[8]);
793 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL2, bc->bc_data[9]);
794 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_CTL5, bc->bc_data[10]);
795 	BWN_RF_WRITE(mac, BWN_B2063_PA_CTL11, bc->bc_data[11]);
796 
797 	old = BWN_RF_READ(mac, BWN_B2063_COM15);
798 	BWN_RF_SET(mac, BWN_B2063_COM15, 0x1e);
799 
800 	freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
801 	freqvco = bc->bc_freq << ((bc->bc_freq > 4000) ? 1 : 2);
802 	freqref = freqxtal * 3;
803 	div = (freqxtal <= 26000000 ? 1 : 2);
804 	timeout = ((((8 * freqxtal) / (div * 5000000)) + 1) >> 1) - 1;
805 	timeoutref = ((((8 * freqxtal) / (div * (timeout + 1))) +
806 		999999) / 1000000) + 1;
807 
808 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB3, 0x2);
809 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB6,
810 	    0xfff8, timeout >> 2);
811 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
812 	    0xff9f,timeout << 5);
813 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB5, timeoutref);
814 
815 	val[0] = bwn_phy_lp_roundup(freqxtal, 1000000, 16);
816 	val[1] = bwn_phy_lp_roundup(freqxtal, 1000000 * div, 16);
817 	val[2] = bwn_phy_lp_roundup(freqvco, 3, 16);
818 
819 	count = (bwn_phy_lp_roundup(val[2], val[1] + 16, 16) * (timeout + 1) *
820 	    (timeoutref + 1)) - 1;
821 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_VCO_CALIB7,
822 	    0xf0, count >> 8);
823 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_VCO_CALIB8, count & 0xff);
824 
825 	tmp[0] = ((val[2] * 62500) / freqref) << 4;
826 	tmp[1] = ((val[2] * 62500) % freqref) << 4;
827 	while (tmp[1] >= freqref) {
828 		tmp[0]++;
829 		tmp[1] -= freqref;
830 	}
831 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG1, 0xffe0, tmp[0] >> 4);
832 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfe0f, tmp[0] << 4);
833 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_SG2, 0xfff0, tmp[0] >> 16);
834 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG3, (tmp[1] >> 8) & 0xff);
835 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_SG4, tmp[1] & 0xff);
836 
837 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF1, 0xb9);
838 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF2, 0x88);
839 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF3, 0x28);
840 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_LF4, 0x63);
841 
842 	tmp[2] = ((41 * (val[2] - 3000)) /1200) + 27;
843 	tmp[3] = bwn_phy_lp_roundup(132000 * tmp[0], 8451, 16);
844 
845 	if (howmany(tmp[3], tmp[2]) > 60) {
846 		scale = 1;
847 		tmp[4] = ((tmp[3] + tmp[2]) / (tmp[2] << 1)) - 8;
848 	} else {
849 		scale = 0;
850 		tmp[4] = ((tmp[3] + (tmp[2] >> 1)) / tmp[2]) - 8;
851 	}
852 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffc0, tmp[4]);
853 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP2, 0xffbf, scale << 6);
854 
855 	tmp[5] = bwn_phy_lp_roundup(100 * val[0], val[2], 16) * (tmp[4] * 8) *
856 	    (scale + 1);
857 	if (tmp[5] > 150)
858 		tmp[5] = 0;
859 
860 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffe0, tmp[5]);
861 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_CP3, 0xffdf, scale << 5);
862 
863 	BWN_RF_SETMASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfffb, 0x4);
864 	if (freqxtal > 26000000)
865 		BWN_RF_SET(mac, BWN_B2063_JTAG_XTAL_12, 0x2);
866 	else
867 		BWN_RF_MASK(mac, BWN_B2063_JTAG_XTAL_12, 0xfd);
868 
869 	if (val[0] == 45)
870 		BWN_RF_SET(mac, BWN_B2063_JTAG_VCO1, 0x2);
871 	else
872 		BWN_RF_MASK(mac, BWN_B2063_JTAG_VCO1, 0xfd);
873 
874 	BWN_RF_SET(mac, BWN_B2063_PLL_SP2, 0x3);
875 	DELAY(1);
876 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP2, 0xfffc);
877 
878 	/* VCO Calibration */
879 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, ~0x40);
880 	tmp16 = BWN_RF_READ(mac, BWN_B2063_JTAG_CALNRST) & 0xf8;
881 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16);
882 	DELAY(1);
883 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x4);
884 	DELAY(1);
885 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x6);
886 	DELAY(1);
887 	BWN_RF_WRITE(mac, BWN_B2063_JTAG_CALNRST, tmp16 | 0x7);
888 	DELAY(300);
889 	BWN_RF_SET(mac, BWN_B2063_PLL_SP1, 0x40);
890 
891 	BWN_RF_WRITE(mac, BWN_B2063_COM15, old);
892 	return (0);
893 }
894 
895 static int
896 bwn_phy_lp_b2062_switch_channel(struct bwn_mac *mac, uint8_t chan)
897 {
898 	struct bwn_softc *sc = mac->mac_sc;
899 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
900 	const struct bwn_b206x_chan *bc = NULL;
901 	uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
902 	uint32_t tmp[9];
903 	int i;
904 
905 	for (i = 0; i < N(bwn_b2062_chantable); i++) {
906 		if (bwn_b2062_chantable[i].bc_chan == chan) {
907 			bc = &bwn_b2062_chantable[i];
908 			break;
909 		}
910 	}
911 
912 	if (bc == NULL)
913 		return (EINVAL);
914 
915 	BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL14, 0x04);
916 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE0, bc->bc_data[0]);
917 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE2, bc->bc_data[1]);
918 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENATUNE3, bc->bc_data[2]);
919 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_TUNE, bc->bc_data[3]);
920 	BWN_RF_WRITE(mac, BWN_B2062_S_LGENG_CTL1, bc->bc_data[4]);
921 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL5, bc->bc_data[5]);
922 	BWN_RF_WRITE(mac, BWN_B2062_N_LGENACTL6, bc->bc_data[6]);
923 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_PGA, bc->bc_data[7]);
924 	BWN_RF_WRITE(mac, BWN_B2062_N_TX_PAD, bc->bc_data[8]);
925 
926 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xcc);
927 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0x07);
928 	bwn_phy_lp_b2062_reset_pllbias(mac);
929 	tmp[0] = freqxtal / 1000;
930 	tmp[1] = plp->plp_div * 1000;
931 	tmp[2] = tmp[1] * ieee80211_ieee2mhz(chan, 0);
932 	if (ieee80211_ieee2mhz(chan, 0) < 4000)
933 		tmp[2] *= 2;
934 	tmp[3] = 48 * tmp[0];
935 	tmp[5] = tmp[2] / tmp[3];
936 	tmp[6] = tmp[2] % tmp[3];
937 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL26, tmp[5]);
938 	tmp[4] = tmp[6] * 0x100;
939 	tmp[5] = tmp[4] / tmp[3];
940 	tmp[6] = tmp[4] % tmp[3];
941 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL27, tmp[5]);
942 	tmp[4] = tmp[6] * 0x100;
943 	tmp[5] = tmp[4] / tmp[3];
944 	tmp[6] = tmp[4] % tmp[3];
945 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL28, tmp[5]);
946 	tmp[4] = tmp[6] * 0x100;
947 	tmp[5] = tmp[4] / tmp[3];
948 	tmp[6] = tmp[4] % tmp[3];
949 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL29,
950 	    tmp[5] + ((2 * tmp[6]) / tmp[3]));
951 	tmp[7] = BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL19);
952 	tmp[8] = ((2 * tmp[2] * (tmp[7] + 1)) + (3 * tmp[0])) / (6 * tmp[0]);
953 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL23, (tmp[8] >> 8) + 16);
954 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL24, tmp[8] & 0xff);
955 
956 	bwn_phy_lp_b2062_vco_calib(mac);
957 	if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
958 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL33, 0xfc);
959 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL34, 0);
960 		bwn_phy_lp_b2062_reset_pllbias(mac);
961 		bwn_phy_lp_b2062_vco_calib(mac);
962 		if (BWN_RF_READ(mac, BWN_B2062_S_RFPLLCTL3) & 0x10) {
963 			BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
964 			return (EIO);
965 		}
966 	}
967 	BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL14, ~0x04);
968 	return (0);
969 }
970 
971 static void
972 bwn_phy_lp_set_anafilter(struct bwn_mac *mac, uint8_t channel)
973 {
974 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
975 	uint16_t tmp = (channel == 14);
976 
977 	if (mac->mac_phy.rev < 2) {
978 		BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xfcff, tmp << 9);
979 		if ((mac->mac_phy.rev == 1) && (plp->plp_rccap))
980 			bwn_phy_lp_set_rccap(mac);
981 		return;
982 	}
983 
984 	BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, 0x3f);
985 }
986 
987 static void
988 bwn_phy_lp_set_gaintbl(struct bwn_mac *mac, uint32_t freq)
989 {
990 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
991 	struct bwn_softc *sc = mac->mac_sc;
992 	struct ieee80211com *ic = &sc->sc_ic;
993 	uint16_t iso, tmp[3];
994 
995 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
996 
997 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
998 		iso = plp->plp_txisoband_m;
999 	else if (freq <= 5320)
1000 		iso = plp->plp_txisoband_l;
1001 	else if (freq <= 5700)
1002 		iso = plp->plp_txisoband_m;
1003 	else
1004 		iso = plp->plp_txisoband_h;
1005 
1006 	tmp[0] = ((iso - 26) / 12) << 12;
1007 	tmp[1] = tmp[0] + 0x1000;
1008 	tmp[2] = tmp[0] + 0x2000;
1009 
1010 	bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), 3, tmp);
1011 	bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), 3, tmp);
1012 }
1013 
1014 static void
1015 bwn_phy_lp_digflt_save(struct bwn_mac *mac)
1016 {
1017 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
1018 	int i;
1019 	static const uint16_t addr[] = {
1020 		BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
1021 		BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
1022 		BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
1023 		BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
1024 		BWN_PHY_OFDM(0xcf),
1025 	};
1026 	static const uint16_t val[] = {
1027 		0xde5e, 0xe832, 0xe331, 0x4d26,
1028 		0x0026, 0x1420, 0x0020, 0xfe08,
1029 		0x0008,
1030 	};
1031 
1032 	for (i = 0; i < N(addr); i++) {
1033 		plp->plp_digfilt[i] = BWN_PHY_READ(mac, addr[i]);
1034 		BWN_PHY_WRITE(mac, addr[i], val[i]);
1035 	}
1036 }
1037 
1038 static void
1039 bwn_phy_lp_get_txpctlmode(struct bwn_mac *mac)
1040 {
1041 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
1042 	struct bwn_softc *sc = mac->mac_sc;
1043 	uint16_t ctl;
1044 
1045 	ctl = BWN_PHY_READ(mac, BWN_PHY_TX_PWR_CTL_CMD);
1046 	switch (ctl & BWN_PHY_TX_PWR_CTL_CMD_MODE) {
1047 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF:
1048 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_OFF;
1049 		break;
1050 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_SW:
1051 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_SW;
1052 		break;
1053 	case BWN_PHY_TX_PWR_CTL_CMD_MODE_HW:
1054 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_ON_HW;
1055 		break;
1056 	default:
1057 		plp->plp_txpctlmode = BWN_PHYLP_TXPCTL_UNKNOWN;
1058 		device_printf(sc->sc_dev, "unknown command mode\n");
1059 		break;
1060 	}
1061 }
1062 
1063 static void
1064 bwn_phy_lp_set_txpctlmode(struct bwn_mac *mac, uint8_t mode)
1065 {
1066 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
1067 	uint16_t ctl;
1068 	uint8_t old;
1069 
1070 	bwn_phy_lp_get_txpctlmode(mac);
1071 	old = plp->plp_txpctlmode;
1072 	if (old == mode)
1073 		return;
1074 	plp->plp_txpctlmode = mode;
1075 
1076 	if (old != BWN_PHYLP_TXPCTL_ON_HW && mode == BWN_PHYLP_TXPCTL_ON_HW) {
1077 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD, 0xff80,
1078 		    plp->plp_tssiidx);
1079 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_NNUM,
1080 		    0x8fff, ((uint16_t)plp->plp_tssinpt << 16));
1081 
1082 		/* disable TX GAIN override */
1083 		if (mac->mac_phy.rev < 2)
1084 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfeff);
1085 		else {
1086 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xff7f);
1087 			BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xbfff);
1088 		}
1089 		BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVR, 0xffbf);
1090 
1091 		plp->plp_txpwridx = -1;
1092 	}
1093 	if (mac->mac_phy.rev >= 2) {
1094 		if (mode == BWN_PHYLP_TXPCTL_ON_HW)
1095 			BWN_PHY_SET(mac, BWN_PHY_OFDM(0xd0), 0x2);
1096 		else
1097 			BWN_PHY_MASK(mac, BWN_PHY_OFDM(0xd0), 0xfffd);
1098 	}
1099 
1100 	/* writes TX Power Control mode */
1101 	switch (plp->plp_txpctlmode) {
1102 	case BWN_PHYLP_TXPCTL_OFF:
1103 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_OFF;
1104 		break;
1105 	case BWN_PHYLP_TXPCTL_ON_HW:
1106 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_HW;
1107 		break;
1108 	case BWN_PHYLP_TXPCTL_ON_SW:
1109 		ctl = BWN_PHY_TX_PWR_CTL_CMD_MODE_SW;
1110 		break;
1111 	default:
1112 		ctl = 0;
1113 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
1114 	}
1115 	BWN_PHY_SETMASK(mac, BWN_PHY_TX_PWR_CTL_CMD,
1116 	    (uint16_t)~BWN_PHY_TX_PWR_CTL_CMD_MODE, ctl);
1117 }
1118 
1119 static void
1120 bwn_phy_lp_bugfix(struct bwn_mac *mac)
1121 {
1122 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
1123 	struct bwn_softc *sc = mac->mac_sc;
1124 	const unsigned int size = 256;
1125 	struct bwn_txgain tg;
1126 	uint32_t rxcomp, txgain, coeff, rfpwr, *tabs;
1127 	uint16_t tssinpt, tssiidx, value[2];
1128 	uint8_t mode;
1129 	int8_t txpwridx;
1130 
1131 	tabs = (uint32_t *)malloc(sizeof(uint32_t) * size, M_DEVBUF,
1132 	    M_NOWAIT | M_ZERO);
1133 	if (tabs == NULL) {
1134 		device_printf(sc->sc_dev, "failed to allocate buffer.\n");
1135 		return;
1136 	}
1137 
1138 	bwn_phy_lp_get_txpctlmode(mac);
1139 	mode = plp->plp_txpctlmode;
1140 	txpwridx = plp->plp_txpwridx;
1141 	tssinpt = plp->plp_tssinpt;
1142 	tssiidx = plp->plp_tssiidx;
1143 
1144 	bwn_tab_read_multi(mac,
1145 	    (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
1146 	    BWN_TAB_4(7, 0x140), size, tabs);
1147 
1148 	bwn_phy_lp_tblinit(mac);
1149 	bwn_phy_lp_bbinit(mac);
1150 	bwn_phy_lp_txpctl_init(mac);
1151 	bwn_phy_lp_rf_onoff(mac, 1);
1152 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
1153 
1154 	bwn_tab_write_multi(mac,
1155 	    (mac->mac_phy.rev < 2) ? BWN_TAB_4(10, 0x140) :
1156 	    BWN_TAB_4(7, 0x140), size, tabs);
1157 
1158 	BWN_WRITE_2(mac, BWN_CHANNEL, plp->plp_chan);
1159 	plp->plp_tssinpt = tssinpt;
1160 	plp->plp_tssiidx = tssiidx;
1161 	bwn_phy_lp_set_anafilter(mac, plp->plp_chan);
1162 	if (txpwridx != -1) {
1163 		/* set TX power by index */
1164 		plp->plp_txpwridx = txpwridx;
1165 		bwn_phy_lp_get_txpctlmode(mac);
1166 		if (plp->plp_txpctlmode != BWN_PHYLP_TXPCTL_OFF)
1167 			bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_ON_SW);
1168 		if (mac->mac_phy.rev >= 2) {
1169 			rxcomp = bwn_tab_read(mac,
1170 			    BWN_TAB_4(7, txpwridx + 320));
1171 			txgain = bwn_tab_read(mac,
1172 			    BWN_TAB_4(7, txpwridx + 192));
1173 			tg.tg_pad = (txgain >> 16) & 0xff;
1174 			tg.tg_gm = txgain & 0xff;
1175 			tg.tg_pga = (txgain >> 8) & 0xff;
1176 			tg.tg_dac = (rxcomp >> 28) & 0xff;
1177 			bwn_phy_lp_set_txgain(mac, &tg);
1178 		} else {
1179 			rxcomp = bwn_tab_read(mac,
1180 			    BWN_TAB_4(10, txpwridx + 320));
1181 			txgain = bwn_tab_read(mac,
1182 			    BWN_TAB_4(10, txpwridx + 192));
1183 			BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
1184 			    0xf800, (txgain >> 4) & 0x7fff);
1185 			bwn_phy_lp_set_txgain_dac(mac, txgain & 0x7);
1186 			bwn_phy_lp_set_txgain_pa(mac, (txgain >> 24) & 0x7f);
1187 		}
1188 		bwn_phy_lp_set_bbmult(mac, (rxcomp >> 20) & 0xff);
1189 
1190 		/* set TX IQCC */
1191 		value[0] = (rxcomp >> 10) & 0x3ff;
1192 		value[1] = rxcomp & 0x3ff;
1193 		bwn_tab_write_multi(mac, BWN_TAB_2(0, 80), 2, value);
1194 
1195 		coeff = bwn_tab_read(mac,
1196 		    (mac->mac_phy.rev >= 2) ? BWN_TAB_4(7, txpwridx + 448) :
1197 		    BWN_TAB_4(10, txpwridx + 448));
1198 		bwn_tab_write(mac, BWN_TAB_2(0, 85), coeff & 0xffff);
1199 		if (mac->mac_phy.rev >= 2) {
1200 			rfpwr = bwn_tab_read(mac,
1201 			    BWN_TAB_4(7, txpwridx + 576));
1202 			BWN_PHY_SETMASK(mac, BWN_PHY_RF_PWR_OVERRIDE, 0xff00,
1203 			    rfpwr & 0xffff);
1204 		}
1205 		bwn_phy_lp_set_txgain_override(mac);
1206 	}
1207 	if (plp->plp_rccap)
1208 		bwn_phy_lp_set_rccap(mac);
1209 	bwn_phy_lp_set_antenna(mac, plp->plp_antenna);
1210 	bwn_phy_lp_set_txpctlmode(mac, mode);
1211 	free(tabs, M_DEVBUF);
1212 }
1213 
1214 static void
1215 bwn_phy_lp_digflt_restore(struct bwn_mac *mac)
1216 {
1217 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
1218 	int i;
1219 	static const uint16_t addr[] = {
1220 		BWN_PHY_OFDM(0xc1), BWN_PHY_OFDM(0xc2),
1221 		BWN_PHY_OFDM(0xc3), BWN_PHY_OFDM(0xc4),
1222 		BWN_PHY_OFDM(0xc5), BWN_PHY_OFDM(0xc6),
1223 		BWN_PHY_OFDM(0xc7), BWN_PHY_OFDM(0xc8),
1224 		BWN_PHY_OFDM(0xcf),
1225 	};
1226 
1227 	for (i = 0; i < N(addr); i++)
1228 		BWN_PHY_WRITE(mac, addr[i], plp->plp_digfilt[i]);
1229 }
1230 
1231 static void
1232 bwn_phy_lp_tblinit(struct bwn_mac *mac)
1233 {
1234 	uint32_t freq = ieee80211_ieee2mhz(bwn_phy_lp_get_default_chan(mac), 0);
1235 
1236 	if (mac->mac_phy.rev < 2) {
1237 		bwn_phy_lp_tblinit_r01(mac);
1238 		bwn_phy_lp_tblinit_txgain(mac);
1239 		bwn_phy_lp_set_gaintbl(mac, freq);
1240 		return;
1241 	}
1242 
1243 	bwn_phy_lp_tblinit_r2(mac);
1244 	bwn_phy_lp_tblinit_txgain(mac);
1245 }
1246 
1247 struct bwn_wpair {
1248 	uint16_t		reg;
1249 	uint16_t		value;
1250 };
1251 
1252 struct bwn_smpair {
1253 	uint16_t		offset;
1254 	uint16_t		mask;
1255 	uint16_t		set;
1256 };
1257 
1258 static void
1259 bwn_phy_lp_bbinit_r2(struct bwn_mac *mac)
1260 {
1261 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
1262 	struct bwn_softc *sc = mac->mac_sc;
1263 	struct ieee80211com *ic = &sc->sc_ic;
1264 	static const struct bwn_wpair v1[] = {
1265 		{ BWN_PHY_AFE_DAC_CTL, 0x50 },
1266 		{ BWN_PHY_AFE_CTL, 0x8800 },
1267 		{ BWN_PHY_AFE_CTL_OVR, 0 },
1268 		{ BWN_PHY_AFE_CTL_OVRVAL, 0 },
1269 		{ BWN_PHY_RF_OVERRIDE_0, 0 },
1270 		{ BWN_PHY_RF_OVERRIDE_2, 0 },
1271 		{ BWN_PHY_OFDM(0xf9), 0 },
1272 		{ BWN_PHY_TR_LOOKUP_1, 0 }
1273 	};
1274 	static const struct bwn_smpair v2[] = {
1275 		{ BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0xb4 },
1276 		{ BWN_PHY_DCOFFSETTRANSIENT, 0xf8ff, 0x200 },
1277 		{ BWN_PHY_DCOFFSETTRANSIENT, 0xff00, 0x7f },
1278 		{ BWN_PHY_GAINDIRECTMISMATCH, 0xff0f, 0x40 },
1279 		{ BWN_PHY_PREAMBLECONFIRMTO, 0xff00, 0x2 }
1280 	};
1281 	static const struct bwn_smpair v3[] = {
1282 		{ BWN_PHY_OFDM(0xfe), 0xffe0, 0x1f },
1283 		{ BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
1284 		{ BWN_PHY_OFDM(0x100), 0xff00, 0x19 },
1285 		{ BWN_PHY_OFDM(0xff), 0x03ff, 0x3c00 },
1286 		{ BWN_PHY_OFDM(0xfe), 0xfc1f, 0x3e0 },
1287 		{ BWN_PHY_OFDM(0xff), 0xffe0, 0xc },
1288 		{ BWN_PHY_OFDM(0x100), 0x00ff, 0x1900 },
1289 		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800 },
1290 		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x12 },
1291 		{ BWN_PHY_GAINMISMATCH, 0x0fff, 0x9000 },
1292 
1293 	};
1294 	int i;
1295 
1296 	for (i = 0; i < N(v1); i++)
1297 		BWN_PHY_WRITE(mac, v1[i].reg, v1[i].value);
1298 	BWN_PHY_SET(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x10);
1299 	for (i = 0; i < N(v2); i++)
1300 		BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask, v2[i].set);
1301 
1302 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x4000);
1303 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x2000);
1304 	BWN_PHY_SET(mac, BWN_PHY_OFDM(0x10a), 0x1);
1305 	if (siba_get_pci_revid(sc->sc_dev) >= 0x18) {
1306 		bwn_tab_write(mac, BWN_TAB_4(17, 65), 0xec);
1307 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x14);
1308 	} else {
1309 		BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0x10a), 0xff01, 0x10);
1310 	}
1311 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0xff00, 0xf4);
1312 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xdf), 0x00ff, 0xf100);
1313 	BWN_PHY_WRITE(mac, BWN_PHY_CLIPTHRESH, 0x48);
1314 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0xff00, 0x46);
1315 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe4), 0xff00, 0x10);
1316 	BWN_PHY_SETMASK(mac, BWN_PHY_PWR_THRESH1, 0xfff0, 0x9);
1317 	BWN_PHY_MASK(mac, BWN_PHY_GAINDIRECTMISMATCH, ~0xf);
1318 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5500);
1319 	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0xa0);
1320 	BWN_PHY_SETMASK(mac, BWN_PHY_GAINDIRECTMISMATCH, 0xe0ff, 0x300);
1321 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2a00);
1322 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
1323 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
1324 		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
1325 		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xa);
1326 	} else {
1327 		BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x1e00);
1328 		BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0xd);
1329 	}
1330 	for (i = 0; i < N(v3); i++)
1331 		BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask, v3[i].set);
1332 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
1333 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
1334 		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x14), 0);
1335 		bwn_tab_write(mac, BWN_TAB_2(0x08, 0x12), 0x40);
1336 	}
1337 
1338 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
1339 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x40);
1340 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0xb00);
1341 		BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x6);
1342 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0x9d00);
1343 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0xff00, 0xa1);
1344 		BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
1345 	} else
1346 		BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, ~0x40);
1347 
1348 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0xff00, 0xb3);
1349 	BWN_PHY_SETMASK(mac, BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00);
1350 	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB, 0xff00, plp->plp_rxpwroffset);
1351 	BWN_PHY_SET(mac, BWN_PHY_RESET_CTL, 0x44);
1352 	BWN_PHY_WRITE(mac, BWN_PHY_RESET_CTL, 0x80);
1353 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, 0xa954);
1354 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_1,
1355 	    0x2000 | ((uint16_t)plp->plp_rssigs << 10) |
1356 	    ((uint16_t)plp->plp_rssivc << 4) | plp->plp_rssivf);
1357 
1358 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
1359 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
1360 		BWN_PHY_SET(mac, BWN_PHY_AFE_ADC_CTL_0, 0x1c);
1361 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_CTL, 0x00ff, 0x8800);
1362 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_1, 0xfc3c, 0x0400);
1363 	}
1364 
1365 	bwn_phy_lp_digflt_save(mac);
1366 }
1367 
1368 static void
1369 bwn_phy_lp_bbinit_r01(struct bwn_mac *mac)
1370 {
1371 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
1372 	struct bwn_softc *sc = mac->mac_sc;
1373 	struct ieee80211com *ic = &sc->sc_ic;
1374 	static const struct bwn_smpair v1[] = {
1375 		{ BWN_PHY_CLIPCTRTHRESH, 0xffe0, 0x0005 },
1376 		{ BWN_PHY_CLIPCTRTHRESH, 0xfc1f, 0x0180 },
1377 		{ BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x3c00 },
1378 		{ BWN_PHY_GAINDIRECTMISMATCH, 0xfff0, 0x0005 },
1379 		{ BWN_PHY_GAIN_MISMATCH_LIMIT, 0xffc0, 0x001a },
1380 		{ BWN_PHY_CRS_ED_THRESH, 0xff00, 0x00b3 },
1381 		{ BWN_PHY_CRS_ED_THRESH, 0x00ff, 0xad00 }
1382 	};
1383 	static const struct bwn_smpair v2[] = {
1384 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
1385 		{ BWN_PHY_TR_LOOKUP_1, 0x3f00, 0x0900 },
1386 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
1387 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
1388 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x000a },
1389 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0400 },
1390 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x000a },
1391 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0b00 },
1392 		{ BWN_PHY_TR_LOOKUP_5, 0xffc0, 0x000a },
1393 		{ BWN_PHY_TR_LOOKUP_5, 0xc0ff, 0x0900 },
1394 		{ BWN_PHY_TR_LOOKUP_6, 0xffc0, 0x000a },
1395 		{ BWN_PHY_TR_LOOKUP_6, 0xc0ff, 0x0b00 },
1396 		{ BWN_PHY_TR_LOOKUP_7, 0xffc0, 0x000a },
1397 		{ BWN_PHY_TR_LOOKUP_7, 0xc0ff, 0x0900 },
1398 		{ BWN_PHY_TR_LOOKUP_8, 0xffc0, 0x000a },
1399 		{ BWN_PHY_TR_LOOKUP_8, 0xc0ff, 0x0b00 }
1400 	};
1401 	static const struct bwn_smpair v3[] = {
1402 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0001 },
1403 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0400 },
1404 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0001 },
1405 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0500 },
1406 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
1407 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0800 },
1408 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
1409 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0a00 }
1410 	};
1411 	static const struct bwn_smpair v4[] = {
1412 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x0004 },
1413 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0800 },
1414 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x0004 },
1415 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0c00 },
1416 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0002 },
1417 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0100 },
1418 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0002 },
1419 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0300 }
1420 	};
1421 	static const struct bwn_smpair v5[] = {
1422 		{ BWN_PHY_TR_LOOKUP_1, 0xffc0, 0x000a },
1423 		{ BWN_PHY_TR_LOOKUP_1, 0xc0ff, 0x0900 },
1424 		{ BWN_PHY_TR_LOOKUP_2, 0xffc0, 0x000a },
1425 		{ BWN_PHY_TR_LOOKUP_2, 0xc0ff, 0x0b00 },
1426 		{ BWN_PHY_TR_LOOKUP_3, 0xffc0, 0x0006 },
1427 		{ BWN_PHY_TR_LOOKUP_3, 0xc0ff, 0x0500 },
1428 		{ BWN_PHY_TR_LOOKUP_4, 0xffc0, 0x0006 },
1429 		{ BWN_PHY_TR_LOOKUP_4, 0xc0ff, 0x0700 }
1430 	};
1431 	int i;
1432 	uint16_t tmp, tmp2;
1433 
1434 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf7ff);
1435 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL, 0);
1436 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, 0);
1437 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, 0);
1438 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0);
1439 	BWN_PHY_SET(mac, BWN_PHY_AFE_DAC_CTL, 0x0004);
1440 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDMSYNCTHRESH0, 0xff00, 0x0078);
1441 	BWN_PHY_SETMASK(mac, BWN_PHY_CLIPCTRTHRESH, 0x83ff, 0x5800);
1442 	BWN_PHY_WRITE(mac, BWN_PHY_ADC_COMPENSATION_CTL, 0x0016);
1443 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_ADC_CTL_0, 0xfff8, 0x0004);
1444 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0x00ff, 0x5400);
1445 	BWN_PHY_SETMASK(mac, BWN_PHY_HIGAINDB, 0x00ff, 0x2400);
1446 	BWN_PHY_SETMASK(mac, BWN_PHY_LOWGAINDB, 0x00ff, 0x2100);
1447 	BWN_PHY_SETMASK(mac, BWN_PHY_VERYLOWGAINDB, 0xff00, 0x0006);
1448 	BWN_PHY_MASK(mac, BWN_PHY_RX_RADIO_CTL, 0xfffe);
1449 	for (i = 0; i < N(v1); i++)
1450 		BWN_PHY_SETMASK(mac, v1[i].offset, v1[i].mask, v1[i].set);
1451 	BWN_PHY_SETMASK(mac, BWN_PHY_INPUT_PWRDB,
1452 	    0xff00, plp->plp_rxpwroffset);
1453 	if ((siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM) &&
1454 	    ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ||
1455 	   (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF))) {
1456 		siba_cc_pmu_set_ldovolt(sc->sc_dev, SIBA_LDO_PAREF, 0x28);
1457 		siba_cc_pmu_set_ldoparef(sc->sc_dev, 1);
1458 		if (mac->mac_phy.rev == 0)
1459 			BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT,
1460 			    0xffcf, 0x0010);
1461 		bwn_tab_write(mac, BWN_TAB_2(11, 7), 60);
1462 	} else {
1463 		siba_cc_pmu_set_ldoparef(sc->sc_dev, 0);
1464 		BWN_PHY_SETMASK(mac, BWN_PHY_LP_RF_SIGNAL_LUT, 0xffcf, 0x0020);
1465 		bwn_tab_write(mac, BWN_TAB_2(11, 7), 100);
1466 	}
1467 	tmp = plp->plp_rssivf | plp->plp_rssivc << 4 | 0xa000;
1468 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_RSSI_CTL_0, tmp);
1469 	if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_RSSIINV)
1470 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x0aaa);
1471 	else
1472 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_RSSI_CTL_1, 0xf000, 0x02aa);
1473 	bwn_tab_write(mac, BWN_TAB_2(11, 1), 24);
1474 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_RADIO_CTL,
1475 	    0xfff9, (plp->plp_bxarch << 1));
1476 	if (mac->mac_phy.rev == 1 &&
1477 	    (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT)) {
1478 		for (i = 0; i < N(v2); i++)
1479 			BWN_PHY_SETMASK(mac, v2[i].offset, v2[i].mask,
1480 			    v2[i].set);
1481 	} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ||
1482 	    (siba_get_pci_subdevice(sc->sc_dev) == 0x048a) ||
1483 	    ((mac->mac_phy.rev == 0) &&
1484 	     (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM))) {
1485 		for (i = 0; i < N(v3); i++)
1486 			BWN_PHY_SETMASK(mac, v3[i].offset, v3[i].mask,
1487 			    v3[i].set);
1488 	} else if (mac->mac_phy.rev == 1 ||
1489 		  (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_FEM)) {
1490 		for (i = 0; i < N(v4); i++)
1491 			BWN_PHY_SETMASK(mac, v4[i].offset, v4[i].mask,
1492 			    v4[i].set);
1493 	} else {
1494 		for (i = 0; i < N(v5); i++)
1495 			BWN_PHY_SETMASK(mac, v5[i].offset, v5[i].mask,
1496 			    v5[i].set);
1497 	}
1498 	if (mac->mac_phy.rev == 1 &&
1499 	    (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_LDO_PAREF)) {
1500 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_5, BWN_PHY_TR_LOOKUP_1);
1501 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_6, BWN_PHY_TR_LOOKUP_2);
1502 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_7, BWN_PHY_TR_LOOKUP_3);
1503 		BWN_PHY_COPY(mac, BWN_PHY_TR_LOOKUP_8, BWN_PHY_TR_LOOKUP_4);
1504 	}
1505 	if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_FEM_BT) &&
1506 	    (siba_get_chipid(sc->sc_dev) == 0x5354) &&
1507 	    (siba_get_chippkg(sc->sc_dev) == SIBA_CHIPPACK_BCM4712S)) {
1508 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0006);
1509 		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_SELECT, 0x0005);
1510 		BWN_PHY_WRITE(mac, BWN_PHY_GPIO_OUTEN, 0xffff);
1511 		bwn_hf_write(mac, bwn_hf_read(mac) | BWN_HF_PR45960W);
1512 	}
1513 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
1514 		BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x8000);
1515 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x0040);
1516 		BWN_PHY_SETMASK(mac, BWN_PHY_MINPWR_LEVEL, 0x00ff, 0xa400);
1517 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xf0ff, 0x0b00);
1518 		BWN_PHY_SETMASK(mac, BWN_PHY_SYNCPEAKCNT, 0xfff8, 0x0007);
1519 		BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xfff8, 0x0003);
1520 		BWN_PHY_SETMASK(mac, BWN_PHY_DSSS_CONFIRM_CNT, 0xffc7, 0x0020);
1521 		BWN_PHY_MASK(mac, BWN_PHY_IDLEAFTERPKTRXTO, 0x00ff);
1522 	} else {
1523 		BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0x7fff);
1524 		BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xffbf);
1525 	}
1526 	if (mac->mac_phy.rev == 1) {
1527 		tmp = BWN_PHY_READ(mac, BWN_PHY_CLIPCTRTHRESH);
1528 		tmp2 = (tmp & 0x03e0) >> 5;
1529 		tmp2 |= tmp2 << 5;
1530 		BWN_PHY_WRITE(mac, BWN_PHY_4C3, tmp2);
1531 		tmp = BWN_PHY_READ(mac, BWN_PHY_GAINDIRECTMISMATCH);
1532 		tmp2 = (tmp & 0x1f00) >> 8;
1533 		tmp2 |= tmp2 << 5;
1534 		BWN_PHY_WRITE(mac, BWN_PHY_4C4, tmp2);
1535 		tmp = BWN_PHY_READ(mac, BWN_PHY_VERYLOWGAINDB);
1536 		tmp2 = tmp & 0x00ff;
1537 		tmp2 |= tmp << 8;
1538 		BWN_PHY_WRITE(mac, BWN_PHY_4C5, tmp2);
1539 	}
1540 }
1541 
1542 struct bwn_b2062_freq {
1543 	uint16_t		freq;
1544 	uint8_t			value[6];
1545 };
1546 
1547 static void
1548 bwn_phy_lp_b2062_init(struct bwn_mac *mac)
1549 {
1550 #define	CALC_CTL7(freq, div)						\
1551 	(((800000000 * (div) + (freq)) / (2 * (freq)) - 8) & 0xff)
1552 #define	CALC_CTL18(freq, div)						\
1553 	((((100 * (freq) + 16000000 * (div)) / (32000000 * (div))) - 1) & 0xff)
1554 #define	CALC_CTL19(freq, div)						\
1555 	((((2 * (freq) + 1000000 * (div)) / (2000000 * (div))) - 1) & 0xff)
1556 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
1557 	struct bwn_softc *sc = mac->mac_sc;
1558 	struct ieee80211com *ic = &sc->sc_ic;
1559 	static const struct bwn_b2062_freq freqdata_tab[] = {
1560 		{ 12000, { 6, 6, 6, 6, 10, 6 } },
1561 		{ 13000, { 4, 4, 4, 4, 11, 7 } },
1562 		{ 14400, { 3, 3, 3, 3, 12, 7 } },
1563 		{ 16200, { 3, 3, 3, 3, 13, 8 } },
1564 		{ 18000, { 2, 2, 2, 2, 14, 8 } },
1565 		{ 19200, { 1, 1, 1, 1, 14, 9 } }
1566 	};
1567 	static const struct bwn_wpair v1[] = {
1568 		{ BWN_B2062_N_TXCTL3, 0 },
1569 		{ BWN_B2062_N_TXCTL4, 0 },
1570 		{ BWN_B2062_N_TXCTL5, 0 },
1571 		{ BWN_B2062_N_TXCTL6, 0 },
1572 		{ BWN_B2062_N_PDNCTL0, 0x40 },
1573 		{ BWN_B2062_N_PDNCTL0, 0 },
1574 		{ BWN_B2062_N_CALIB_TS, 0x10 },
1575 		{ BWN_B2062_N_CALIB_TS, 0 }
1576 	};
1577 	const struct bwn_b2062_freq *f = NULL;
1578 	uint32_t xtalfreq, ref;
1579 	unsigned int i;
1580 
1581 	bwn_phy_lp_b2062_tblinit(mac);
1582 
1583 	for (i = 0; i < N(v1); i++)
1584 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
1585 	if (mac->mac_phy.rev > 0)
1586 		BWN_RF_WRITE(mac, BWN_B2062_S_BG_CTL1,
1587 		    (BWN_RF_READ(mac, BWN_B2062_N_COM2) >> 1) | 0x80);
1588 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
1589 		BWN_RF_SET(mac, BWN_B2062_N_TSSI_CTL0, 0x1);
1590 	else
1591 		BWN_RF_MASK(mac, BWN_B2062_N_TSSI_CTL0, ~0x1);
1592 
1593 	KASSERT(siba_get_cc_caps(sc->sc_dev) & SIBA_CC_CAPS_PMU,
1594 	    ("%s:%d: fail", __func__, __LINE__));
1595 	xtalfreq = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
1596 	KASSERT(xtalfreq != 0, ("%s:%d: fail", __func__, __LINE__));
1597 
1598 	if (xtalfreq <= 30000000) {
1599 		plp->plp_div = 1;
1600 		BWN_RF_MASK(mac, BWN_B2062_S_RFPLLCTL1, 0xfffb);
1601 	} else {
1602 		plp->plp_div = 2;
1603 		BWN_RF_SET(mac, BWN_B2062_S_RFPLLCTL1, 0x4);
1604 	}
1605 
1606 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL7,
1607 	    CALC_CTL7(xtalfreq, plp->plp_div));
1608 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL18,
1609 	    CALC_CTL18(xtalfreq, plp->plp_div));
1610 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL19,
1611 	    CALC_CTL19(xtalfreq, plp->plp_div));
1612 
1613 	ref = (1000 * plp->plp_div + 2 * xtalfreq) / (2000 * plp->plp_div);
1614 	ref &= 0xffff;
1615 	for (i = 0; i < N(freqdata_tab); i++) {
1616 		if (ref < freqdata_tab[i].freq) {
1617 			f = &freqdata_tab[i];
1618 			break;
1619 		}
1620 	}
1621 	if (f == NULL)
1622 		f = &freqdata_tab[N(freqdata_tab) - 1];
1623 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL8,
1624 	    ((uint16_t)(f->value[1]) << 4) | f->value[0]);
1625 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL9,
1626 	    ((uint16_t)(f->value[3]) << 4) | f->value[2]);
1627 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL10, f->value[4]);
1628 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL11, f->value[5]);
1629 #undef CALC_CTL7
1630 #undef CALC_CTL18
1631 #undef CALC_CTL19
1632 }
1633 
1634 static void
1635 bwn_phy_lp_b2063_init(struct bwn_mac *mac)
1636 {
1637 
1638 	bwn_phy_lp_b2063_tblinit(mac);
1639 	BWN_RF_WRITE(mac, BWN_B2063_LOGEN_SP5, 0);
1640 	BWN_RF_SET(mac, BWN_B2063_COM8, 0x38);
1641 	BWN_RF_WRITE(mac, BWN_B2063_REG_SP1, 0x56);
1642 	BWN_RF_MASK(mac, BWN_B2063_RX_BB_CTL2, ~0x2);
1643 	BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0);
1644 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP6, 0x20);
1645 	BWN_RF_WRITE(mac, BWN_B2063_TX_RF_SP9, 0x40);
1646 	if (mac->mac_phy.rev == 2) {
1647 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0xa0);
1648 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP4, 0xa0);
1649 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x18);
1650 	} else {
1651 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP3, 0x20);
1652 		BWN_RF_WRITE(mac, BWN_B2063_PA_SP2, 0x20);
1653 	}
1654 }
1655 
1656 static void
1657 bwn_phy_lp_rxcal_r2(struct bwn_mac *mac)
1658 {
1659 	struct bwn_softc *sc = mac->mac_sc;
1660 	static const struct bwn_wpair v1[] = {
1661 		{ BWN_B2063_RX_BB_SP8, 0x0 },
1662 		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
1663 		{ BWN_B2063_RC_CALIB_CTL1, 0x7c },
1664 		{ BWN_B2063_RC_CALIB_CTL2, 0x15 },
1665 		{ BWN_B2063_RC_CALIB_CTL3, 0x70 },
1666 		{ BWN_B2063_RC_CALIB_CTL4, 0x52 },
1667 		{ BWN_B2063_RC_CALIB_CTL5, 0x1 },
1668 		{ BWN_B2063_RC_CALIB_CTL1, 0x7d }
1669 	};
1670 	static const struct bwn_wpair v2[] = {
1671 		{ BWN_B2063_TX_BB_SP3, 0x0 },
1672 		{ BWN_B2063_RC_CALIB_CTL1, 0x7e },
1673 		{ BWN_B2063_RC_CALIB_CTL1, 0x7c },
1674 		{ BWN_B2063_RC_CALIB_CTL2, 0x55 },
1675 		{ BWN_B2063_RC_CALIB_CTL3, 0x76 }
1676 	};
1677 	uint32_t freqxtal = siba_get_cc_pmufreq(sc->sc_dev) * 1000;
1678 	int i;
1679 	uint8_t tmp;
1680 
1681 	tmp = BWN_RF_READ(mac, BWN_B2063_RX_BB_SP8) & 0xff;
1682 
1683 	for (i = 0; i < 2; i++)
1684 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
1685 	BWN_RF_MASK(mac, BWN_B2063_PLL_SP1, 0xf7);
1686 	for (i = 2; i < N(v1); i++)
1687 		BWN_RF_WRITE(mac, v1[i].reg, v1[i].value);
1688 	for (i = 0; i < 10000; i++) {
1689 		if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
1690 			break;
1691 		DELAY(1000);
1692 	}
1693 
1694 	if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
1695 		BWN_RF_WRITE(mac, BWN_B2063_RX_BB_SP8, tmp);
1696 
1697 	tmp = BWN_RF_READ(mac, BWN_B2063_TX_BB_SP3) & 0xff;
1698 
1699 	for (i = 0; i < N(v2); i++)
1700 		BWN_RF_WRITE(mac, v2[i].reg, v2[i].value);
1701 	if (freqxtal == 24000000) {
1702 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0xfc);
1703 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x0);
1704 	} else {
1705 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL4, 0x13);
1706 		BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL5, 0x1);
1707 	}
1708 	BWN_RF_WRITE(mac, BWN_B2063_PA_SP7, 0x7d);
1709 	for (i = 0; i < 10000; i++) {
1710 		if (BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2)
1711 			break;
1712 		DELAY(1000);
1713 	}
1714 	if (!(BWN_RF_READ(mac, BWN_B2063_RC_CALIB_CTL6) & 0x2))
1715 		BWN_RF_WRITE(mac, BWN_B2063_TX_BB_SP3, tmp);
1716 	BWN_RF_WRITE(mac, BWN_B2063_RC_CALIB_CTL1, 0x7e);
1717 }
1718 
1719 static void
1720 bwn_phy_lp_rccal_r12(struct bwn_mac *mac)
1721 {
1722 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
1723 	struct bwn_softc *sc = mac->mac_sc;
1724 	struct bwn_phy_lp_iq_est ie;
1725 	struct bwn_txgain tx_gains;
1726 	static const uint32_t pwrtbl[21] = {
1727 		0x10000, 0x10557, 0x10e2d, 0x113e0, 0x10f22, 0x0ff64,
1728 		0x0eda2, 0x0e5d4, 0x0efd1, 0x0fbe8, 0x0b7b8, 0x04b35,
1729 		0x01a5e, 0x00a0b, 0x00444, 0x001fd, 0x000ff, 0x00088,
1730 		0x0004c, 0x0002c, 0x0001a,
1731 	};
1732 	uint32_t npwr, ipwr, sqpwr, tmp;
1733 	int loopback, i, j, sum, error;
1734 	uint16_t save[7];
1735 	uint8_t txo, bbmult, txpctlmode;
1736 
1737 	error = bwn_phy_lp_switch_channel(mac, 7);
1738 	if (error)
1739 		device_printf(sc->sc_dev,
1740 		    "failed to change channel to 7 (%d)\n", error);
1741 	txo = (BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR) & 0x40) ? 1 : 0;
1742 	bbmult = bwn_phy_lp_get_bbmult(mac);
1743 	if (txo)
1744 		tx_gains = bwn_phy_lp_get_txgain(mac);
1745 
1746 	save[0] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_0);
1747 	save[1] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_VAL_0);
1748 	save[2] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVR);
1749 	save[3] = BWN_PHY_READ(mac, BWN_PHY_AFE_CTL_OVRVAL);
1750 	save[4] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2);
1751 	save[5] = BWN_PHY_READ(mac, BWN_PHY_RF_OVERRIDE_2_VAL);
1752 	save[6] = BWN_PHY_READ(mac, BWN_PHY_LP_PHY_CTL);
1753 
1754 	bwn_phy_lp_get_txpctlmode(mac);
1755 	txpctlmode = plp->plp_txpctlmode;
1756 	bwn_phy_lp_set_txpctlmode(mac, BWN_PHYLP_TXPCTL_OFF);
1757 
1758 	/* disable CRS */
1759 	bwn_phy_lp_set_deaf(mac, 1);
1760 	bwn_phy_lp_set_trsw_over(mac, 0, 1);
1761 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffb);
1762 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x4);
1763 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfff7);
1764 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
1765 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x10);
1766 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
1767 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffdf);
1768 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x20);
1769 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xffbf);
1770 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
1771 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x7);
1772 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x38);
1773 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f);
1774 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0x100);
1775 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfdff);
1776 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL0, 0);
1777 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL1, 1);
1778 	BWN_PHY_WRITE(mac, BWN_PHY_PS_CTL_OVERRIDE_VAL2, 0x20);
1779 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfbff);
1780 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xf7ff);
1781 	BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0);
1782 	BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, 0x45af);
1783 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, 0x3ff);
1784 
1785 	loopback = bwn_phy_lp_loopback(mac);
1786 	if (loopback == -1)
1787 		goto done;
1788 	bwn_phy_lp_set_rxgain_idx(mac, loopback);
1789 	BWN_PHY_SETMASK(mac, BWN_PHY_LP_PHY_CTL, 0xffbf, 0x40);
1790 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xfff8, 0x1);
1791 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xffc7, 0x8);
1792 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL, 0xff3f, 0xc0);
1793 
1794 	tmp = 0;
1795 	memset(&ie, 0, sizeof(ie));
1796 	for (i = 128; i <= 159; i++) {
1797 		BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2, i);
1798 		sum = 0;
1799 		for (j = 5; j <= 25; j++) {
1800 			bwn_phy_lp_ddfs_turnon(mac, 1, 1, j, j, 0);
1801 			if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
1802 				goto done;
1803 			sqpwr = ie.ie_ipwr + ie.ie_qpwr;
1804 			ipwr = ((pwrtbl[j - 5] >> 3) + 1) >> 1;
1805 			npwr = bwn_phy_lp_roundup(sqpwr, (j == 5) ? sqpwr : 0,
1806 			    12);
1807 			sum += ((ipwr - npwr) * (ipwr - npwr));
1808 			if ((i == 128) || (sum < tmp)) {
1809 				plp->plp_rccap = i;
1810 				tmp = sum;
1811 			}
1812 		}
1813 	}
1814 	bwn_phy_lp_ddfs_turnoff(mac);
1815 done:
1816 	/* restore CRS */
1817 	bwn_phy_lp_clear_deaf(mac, 1);
1818 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_0, 0xff80);
1819 	BWN_PHY_MASK(mac, BWN_PHY_RF_OVERRIDE_2, 0xfc00);
1820 
1821 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_VAL_0, save[1]);
1822 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_0, save[0]);
1823 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVRVAL, save[3]);
1824 	BWN_PHY_WRITE(mac, BWN_PHY_AFE_CTL_OVR, save[2]);
1825 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2_VAL, save[5]);
1826 	BWN_PHY_WRITE(mac, BWN_PHY_RF_OVERRIDE_2, save[4]);
1827 	BWN_PHY_WRITE(mac, BWN_PHY_LP_PHY_CTL, save[6]);
1828 
1829 	bwn_phy_lp_set_bbmult(mac, bbmult);
1830 	if (txo)
1831 		bwn_phy_lp_set_txgain(mac, &tx_gains);
1832 	bwn_phy_lp_set_txpctlmode(mac, txpctlmode);
1833 	if (plp->plp_rccap)
1834 		bwn_phy_lp_set_rccap(mac);
1835 }
1836 
1837 static void
1838 bwn_phy_lp_set_rccap(struct bwn_mac *mac)
1839 {
1840 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
1841 	uint8_t rc_cap = (plp->plp_rccap & 0x1f) >> 1;
1842 
1843 	if (mac->mac_phy.rev == 1)
1844 		rc_cap = MIN(rc_cap + 5, 15);
1845 
1846 	BWN_RF_WRITE(mac, BWN_B2062_N_RXBB_CALIB2,
1847 	    MAX(plp->plp_rccap - 4, 0x80));
1848 	BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, rc_cap | 0x80);
1849 	BWN_RF_WRITE(mac, BWN_B2062_S_RXG_CNT16,
1850 	    ((plp->plp_rccap & 0x1f) >> 2) | 0x80);
1851 }
1852 
1853 static uint32_t
1854 bwn_phy_lp_roundup(uint32_t value, uint32_t div, uint8_t pre)
1855 {
1856 	uint32_t i, q, r;
1857 
1858 	if (div == 0)
1859 		return (0);
1860 
1861 	for (i = 0, q = value / div, r = value % div; i < pre; i++) {
1862 		q <<= 1;
1863 		if (r << 1 >= div) {
1864 			q++;
1865 			r = (r << 1) - div;
1866 		}
1867 	}
1868 	if (r << 1 >= div)
1869 		q++;
1870 	return (q);
1871 }
1872 
1873 static void
1874 bwn_phy_lp_b2062_reset_pllbias(struct bwn_mac *mac)
1875 {
1876 	struct bwn_softc *sc = mac->mac_sc;
1877 
1878 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0xff);
1879 	DELAY(20);
1880 	if (siba_get_chipid(sc->sc_dev) == 0x5354) {
1881 		BWN_RF_WRITE(mac, BWN_B2062_N_COM1, 4);
1882 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 4);
1883 	} else {
1884 		BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL2, 0);
1885 	}
1886 	DELAY(5);
1887 }
1888 
1889 static void
1890 bwn_phy_lp_b2062_vco_calib(struct bwn_mac *mac)
1891 {
1892 
1893 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x42);
1894 	BWN_RF_WRITE(mac, BWN_B2062_S_RFPLLCTL21, 0x62);
1895 	DELAY(200);
1896 }
1897 
1898 static void
1899 bwn_phy_lp_b2062_tblinit(struct bwn_mac *mac)
1900 {
1901 #define	FLAG_A	0x01
1902 #define	FLAG_G	0x02
1903 	struct bwn_softc *sc = mac->mac_sc;
1904 	struct ieee80211com *ic = &sc->sc_ic;
1905 	static const struct bwn_b206x_rfinit_entry bwn_b2062_init_tab[] = {
1906 		{ BWN_B2062_N_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
1907 		{ BWN_B2062_N_PDNCTL1, 0x0, 0xca, FLAG_G, },
1908 		{ BWN_B2062_N_PDNCTL3, 0x0, 0x0, FLAG_A | FLAG_G, },
1909 		{ BWN_B2062_N_PDNCTL4, 0x15, 0x2a, FLAG_A | FLAG_G, },
1910 		{ BWN_B2062_N_LGENC, 0xDB, 0xff, FLAG_A, },
1911 		{ BWN_B2062_N_LGENATUNE0, 0xdd, 0x0, FLAG_A | FLAG_G, },
1912 		{ BWN_B2062_N_LGENATUNE2, 0xdd, 0x0, FLAG_A | FLAG_G, },
1913 		{ BWN_B2062_N_LGENATUNE3, 0x77, 0xB5, FLAG_A | FLAG_G, },
1914 		{ BWN_B2062_N_LGENACTL3, 0x0, 0xff, FLAG_A | FLAG_G, },
1915 		{ BWN_B2062_N_LGENACTL7, 0x33, 0x33, FLAG_A | FLAG_G, },
1916 		{ BWN_B2062_N_RXA_CTL1, 0x0, 0x0, FLAG_G, },
1917 		{ BWN_B2062_N_RXBB_CTL0, 0x82, 0x80, FLAG_A | FLAG_G, },
1918 		{ BWN_B2062_N_RXBB_GAIN1, 0x4, 0x4, FLAG_A | FLAG_G, },
1919 		{ BWN_B2062_N_RXBB_GAIN2, 0x0, 0x0, FLAG_A | FLAG_G, },
1920 		{ BWN_B2062_N_TXCTL4, 0x3, 0x3, FLAG_A | FLAG_G, },
1921 		{ BWN_B2062_N_TXCTL5, 0x2, 0x2, FLAG_A | FLAG_G, },
1922 		{ BWN_B2062_N_TX_TUNE, 0x88, 0x1b, FLAG_A | FLAG_G, },
1923 		{ BWN_B2062_S_COM4, 0x1, 0x0, FLAG_A | FLAG_G, },
1924 		{ BWN_B2062_S_PDS_CTL0, 0xff, 0xff, FLAG_A | FLAG_G, },
1925 		{ BWN_B2062_S_LGENG_CTL0, 0xf8, 0xd8, FLAG_A | FLAG_G, },
1926 		{ BWN_B2062_S_LGENG_CTL1, 0x3c, 0x24, FLAG_A | FLAG_G, },
1927 		{ BWN_B2062_S_LGENG_CTL8, 0x88, 0x80, FLAG_A | FLAG_G, },
1928 		{ BWN_B2062_S_LGENG_CTL10, 0x88, 0x80, FLAG_A | FLAG_G, },
1929 		{ BWN_B2062_S_RFPLLCTL0, 0x98, 0x98, FLAG_A | FLAG_G, },
1930 		{ BWN_B2062_S_RFPLLCTL1, 0x10, 0x10, FLAG_A | FLAG_G, },
1931 		{ BWN_B2062_S_RFPLLCTL5, 0x43, 0x43, FLAG_A | FLAG_G, },
1932 		{ BWN_B2062_S_RFPLLCTL6, 0x47, 0x47, FLAG_A | FLAG_G, },
1933 		{ BWN_B2062_S_RFPLLCTL7, 0xc, 0xc, FLAG_A | FLAG_G, },
1934 		{ BWN_B2062_S_RFPLLCTL8, 0x11, 0x11, FLAG_A | FLAG_G, },
1935 		{ BWN_B2062_S_RFPLLCTL9, 0x11, 0x11, FLAG_A | FLAG_G, },
1936 		{ BWN_B2062_S_RFPLLCTL10, 0xe, 0xe, FLAG_A | FLAG_G, },
1937 		{ BWN_B2062_S_RFPLLCTL11, 0x8, 0x8, FLAG_A | FLAG_G, },
1938 		{ BWN_B2062_S_RFPLLCTL12, 0x33, 0x33, FLAG_A | FLAG_G, },
1939 		{ BWN_B2062_S_RFPLLCTL13, 0xa, 0xa, FLAG_A | FLAG_G, },
1940 		{ BWN_B2062_S_RFPLLCTL14, 0x6, 0x6, FLAG_A | FLAG_G, },
1941 		{ BWN_B2062_S_RFPLLCTL18, 0x3e, 0x3e, FLAG_A | FLAG_G, },
1942 		{ BWN_B2062_S_RFPLLCTL19, 0x13, 0x13, FLAG_A | FLAG_G, },
1943 		{ BWN_B2062_S_RFPLLCTL21, 0x62, 0x62, FLAG_A | FLAG_G, },
1944 		{ BWN_B2062_S_RFPLLCTL22, 0x7, 0x7, FLAG_A | FLAG_G, },
1945 		{ BWN_B2062_S_RFPLLCTL23, 0x16, 0x16, FLAG_A | FLAG_G, },
1946 		{ BWN_B2062_S_RFPLLCTL24, 0x5c, 0x5c, FLAG_A | FLAG_G, },
1947 		{ BWN_B2062_S_RFPLLCTL25, 0x95, 0x95, FLAG_A | FLAG_G, },
1948 		{ BWN_B2062_S_RFPLLCTL30, 0xa0, 0xa0, FLAG_A | FLAG_G, },
1949 		{ BWN_B2062_S_RFPLLCTL31, 0x4, 0x4, FLAG_A | FLAG_G, },
1950 		{ BWN_B2062_S_RFPLLCTL33, 0xcc, 0xcc, FLAG_A | FLAG_G, },
1951 		{ BWN_B2062_S_RFPLLCTL34, 0x7, 0x7, FLAG_A | FLAG_G, },
1952 		{ BWN_B2062_S_RXG_CNT8, 0xf, 0xf, FLAG_A, },
1953 	};
1954 	const struct bwn_b206x_rfinit_entry *br;
1955 	unsigned int i;
1956 
1957 	for (i = 0; i < N(bwn_b2062_init_tab); i++) {
1958 		br = &bwn_b2062_init_tab[i];
1959 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
1960 			if (br->br_flags & FLAG_G)
1961 				BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
1962 		} else {
1963 			if (br->br_flags & FLAG_A)
1964 				BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
1965 		}
1966 	}
1967 #undef FLAG_A
1968 #undef FLAG_B
1969 }
1970 
1971 static void
1972 bwn_phy_lp_b2063_tblinit(struct bwn_mac *mac)
1973 {
1974 #define	FLAG_A	0x01
1975 #define	FLAG_G	0x02
1976 	struct bwn_softc *sc = mac->mac_sc;
1977 	struct ieee80211com *ic = &sc->sc_ic;
1978 	static const struct bwn_b206x_rfinit_entry bwn_b2063_init_tab[] = {
1979 		{ BWN_B2063_COM1, 0x0, 0x0, FLAG_G, },
1980 		{ BWN_B2063_COM10, 0x1, 0x0, FLAG_A, },
1981 		{ BWN_B2063_COM16, 0x0, 0x0, FLAG_G, },
1982 		{ BWN_B2063_COM17, 0x0, 0x0, FLAG_G, },
1983 		{ BWN_B2063_COM18, 0x0, 0x0, FLAG_G, },
1984 		{ BWN_B2063_COM19, 0x0, 0x0, FLAG_G, },
1985 		{ BWN_B2063_COM20, 0x0, 0x0, FLAG_G, },
1986 		{ BWN_B2063_COM21, 0x0, 0x0, FLAG_G, },
1987 		{ BWN_B2063_COM22, 0x0, 0x0, FLAG_G, },
1988 		{ BWN_B2063_COM23, 0x0, 0x0, FLAG_G, },
1989 		{ BWN_B2063_COM24, 0x0, 0x0, FLAG_G, },
1990 		{ BWN_B2063_LOGEN_SP1, 0xe8, 0xd4, FLAG_A | FLAG_G, },
1991 		{ BWN_B2063_LOGEN_SP2, 0xa7, 0x53, FLAG_A | FLAG_G, },
1992 		{ BWN_B2063_LOGEN_SP4, 0xf0, 0xf, FLAG_A | FLAG_G, },
1993 		{ BWN_B2063_G_RX_SP1, 0x1f, 0x5e, FLAG_G, },
1994 		{ BWN_B2063_G_RX_SP2, 0x7f, 0x7e, FLAG_G, },
1995 		{ BWN_B2063_G_RX_SP3, 0x30, 0xf0, FLAG_G, },
1996 		{ BWN_B2063_G_RX_SP7, 0x7f, 0x7f, FLAG_A | FLAG_G, },
1997 		{ BWN_B2063_G_RX_SP10, 0xc, 0xc, FLAG_A | FLAG_G, },
1998 		{ BWN_B2063_A_RX_SP1, 0x3c, 0x3f, FLAG_A, },
1999 		{ BWN_B2063_A_RX_SP2, 0xfc, 0xfe, FLAG_A, },
2000 		{ BWN_B2063_A_RX_SP7, 0x8, 0x8, FLAG_A | FLAG_G, },
2001 		{ BWN_B2063_RX_BB_SP4, 0x60, 0x60, FLAG_A | FLAG_G, },
2002 		{ BWN_B2063_RX_BB_SP8, 0x30, 0x30, FLAG_A | FLAG_G, },
2003 		{ BWN_B2063_TX_RF_SP3, 0xc, 0xb, FLAG_A | FLAG_G, },
2004 		{ BWN_B2063_TX_RF_SP4, 0x10, 0xf, FLAG_A | FLAG_G, },
2005 		{ BWN_B2063_PA_SP1, 0x3d, 0xfd, FLAG_A | FLAG_G, },
2006 		{ BWN_B2063_TX_BB_SP1, 0x2, 0x2, FLAG_A | FLAG_G, },
2007 		{ BWN_B2063_BANDGAP_CTL1, 0x56, 0x56, FLAG_A | FLAG_G, },
2008 		{ BWN_B2063_JTAG_VCO2, 0xF7, 0xF7, FLAG_A | FLAG_G, },
2009 		{ BWN_B2063_G_RX_MIX3, 0x71, 0x71, FLAG_A | FLAG_G, },
2010 		{ BWN_B2063_G_RX_MIX4, 0x71, 0x71, FLAG_A | FLAG_G, },
2011 		{ BWN_B2063_A_RX_1ST2, 0xf0, 0x30, FLAG_A, },
2012 		{ BWN_B2063_A_RX_PS6, 0x77, 0x77, FLAG_A | FLAG_G, },
2013 		{ BWN_B2063_A_RX_MIX4, 0x3, 0x3, FLAG_A | FLAG_G, },
2014 		{ BWN_B2063_A_RX_MIX5, 0xf, 0xf, FLAG_A | FLAG_G, },
2015 		{ BWN_B2063_A_RX_MIX6, 0xf, 0xf, FLAG_A | FLAG_G, },
2016 		{ BWN_B2063_RX_TIA_CTL1, 0x77, 0x77, FLAG_A | FLAG_G, },
2017 		{ BWN_B2063_RX_TIA_CTL3, 0x77, 0x77, FLAG_A | FLAG_G, },
2018 		{ BWN_B2063_RX_BB_CTL2, 0x4, 0x4, FLAG_A | FLAG_G, },
2019 		{ BWN_B2063_PA_CTL1, 0x0, 0x4, FLAG_A, },
2020 		{ BWN_B2063_VREG_CTL1, 0x3, 0x3, FLAG_A | FLAG_G, },
2021 	};
2022 	const struct bwn_b206x_rfinit_entry *br;
2023 	unsigned int i;
2024 
2025 	for (i = 0; i < N(bwn_b2063_init_tab); i++) {
2026 		br = &bwn_b2063_init_tab[i];
2027 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
2028 			if (br->br_flags & FLAG_G)
2029 				BWN_RF_WRITE(mac, br->br_offset, br->br_valueg);
2030 		} else {
2031 			if (br->br_flags & FLAG_A)
2032 				BWN_RF_WRITE(mac, br->br_offset, br->br_valuea);
2033 		}
2034 	}
2035 #undef FLAG_A
2036 #undef FLAG_B
2037 }
2038 
2039 static void
2040 bwn_tab_read_multi(struct bwn_mac *mac, uint32_t typenoffset,
2041     int count, void *_data)
2042 {
2043 	unsigned int i;
2044 	uint32_t offset, type;
2045 	uint8_t *data = _data;
2046 
2047 	type = BWN_TAB_GETTYPE(typenoffset);
2048 	offset = BWN_TAB_GETOFFSET(typenoffset);
2049 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
2050 
2051 	BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
2052 
2053 	for (i = 0; i < count; i++) {
2054 		switch (type) {
2055 		case BWN_TAB_8BIT:
2056 			*data = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
2057 			data++;
2058 			break;
2059 		case BWN_TAB_16BIT:
2060 			*((uint16_t *)data) = BWN_PHY_READ(mac,
2061 			    BWN_PHY_TABLEDATALO);
2062 			data += 2;
2063 			break;
2064 		case BWN_TAB_32BIT:
2065 			*((uint32_t *)data) = BWN_PHY_READ(mac,
2066 			    BWN_PHY_TABLEDATAHI);
2067 			*((uint32_t *)data) <<= 16;
2068 			*((uint32_t *)data) |= BWN_PHY_READ(mac,
2069 			    BWN_PHY_TABLEDATALO);
2070 			data += 4;
2071 			break;
2072 		default:
2073 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
2074 		}
2075 	}
2076 }
2077 
2078 static void
2079 bwn_tab_write_multi(struct bwn_mac *mac, uint32_t typenoffset,
2080     int count, const void *_data)
2081 {
2082 	uint32_t offset, type, value;
2083 	const uint8_t *data = _data;
2084 	unsigned int i;
2085 
2086 	type = BWN_TAB_GETTYPE(typenoffset);
2087 	offset = BWN_TAB_GETOFFSET(typenoffset);
2088 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
2089 
2090 	BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
2091 
2092 	for (i = 0; i < count; i++) {
2093 		switch (type) {
2094 		case BWN_TAB_8BIT:
2095 			value = *data;
2096 			data++;
2097 			KASSERT(!(value & ~0xff),
2098 			    ("%s:%d: fail", __func__, __LINE__));
2099 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
2100 			break;
2101 		case BWN_TAB_16BIT:
2102 			value = *((const uint16_t *)data);
2103 			data += 2;
2104 			KASSERT(!(value & ~0xffff),
2105 			    ("%s:%d: fail", __func__, __LINE__));
2106 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
2107 			break;
2108 		case BWN_TAB_32BIT:
2109 			value = *((const uint32_t *)data);
2110 			data += 4;
2111 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
2112 			BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
2113 			break;
2114 		default:
2115 			KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
2116 		}
2117 	}
2118 }
2119 
2120 static struct bwn_txgain
2121 bwn_phy_lp_get_txgain(struct bwn_mac *mac)
2122 {
2123 	struct bwn_txgain tg;
2124 	uint16_t tmp;
2125 
2126 	tg.tg_dac = (BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0x380) >> 7;
2127 	if (mac->mac_phy.rev < 2) {
2128 		tmp = BWN_PHY_READ(mac,
2129 		    BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL) & 0x7ff;
2130 		tg.tg_gm = tmp & 0x0007;
2131 		tg.tg_pga = (tmp & 0x0078) >> 3;
2132 		tg.tg_pad = (tmp & 0x780) >> 7;
2133 		return (tg);
2134 	}
2135 
2136 	tmp = BWN_PHY_READ(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL);
2137 	tg.tg_pad = BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0xff;
2138 	tg.tg_gm = tmp & 0xff;
2139 	tg.tg_pga = (tmp >> 8) & 0xff;
2140 	return (tg);
2141 }
2142 
2143 static uint8_t
2144 bwn_phy_lp_get_bbmult(struct bwn_mac *mac)
2145 {
2146 
2147 	return (bwn_tab_read(mac, BWN_TAB_2(0, 87)) & 0xff00) >> 8;
2148 }
2149 
2150 static void
2151 bwn_phy_lp_set_txgain(struct bwn_mac *mac, struct bwn_txgain *tg)
2152 {
2153 	uint16_t pa;
2154 
2155 	if (mac->mac_phy.rev < 2) {
2156 		BWN_PHY_SETMASK(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL, 0xf800,
2157 		    (tg->tg_pad << 7) | (tg->tg_pga << 3) | tg->tg_gm);
2158 		bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
2159 		bwn_phy_lp_set_txgain_override(mac);
2160 		return;
2161 	}
2162 
2163 	pa = bwn_phy_lp_get_pa_gain(mac);
2164 	BWN_PHY_WRITE(mac, BWN_PHY_TX_GAIN_CTL_OVERRIDE_VAL,
2165 	    (tg->tg_pga << 8) | tg->tg_gm);
2166 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0x8000,
2167 	    tg->tg_pad | (pa << 6));
2168 	BWN_PHY_WRITE(mac, BWN_PHY_OFDM(0xfc), (tg->tg_pga << 8) | tg->tg_gm);
2169 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x8000,
2170 	    tg->tg_pad | (pa << 8));
2171 	bwn_phy_lp_set_txgain_dac(mac, tg->tg_dac);
2172 	bwn_phy_lp_set_txgain_override(mac);
2173 }
2174 
2175 static void
2176 bwn_phy_lp_set_bbmult(struct bwn_mac *mac, uint8_t bbmult)
2177 {
2178 
2179 	bwn_tab_write(mac, BWN_TAB_2(0, 87), (uint16_t)bbmult << 8);
2180 }
2181 
2182 static void
2183 bwn_phy_lp_set_trsw_over(struct bwn_mac *mac, uint8_t tx, uint8_t rx)
2184 {
2185 	uint16_t trsw = (tx << 1) | rx;
2186 
2187 	BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffc, trsw);
2188 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x3);
2189 }
2190 
2191 static void
2192 bwn_phy_lp_set_rxgain(struct bwn_mac *mac, uint32_t gain)
2193 {
2194 	struct bwn_softc *sc = mac->mac_sc;
2195 	struct ieee80211com *ic = &sc->sc_ic;
2196 	uint16_t ext_lna, high_gain, lna, low_gain, trsw, tmp;
2197 
2198 	if (mac->mac_phy.rev < 2) {
2199 		trsw = gain & 0x1;
2200 		lna = (gain & 0xfffc) | ((gain & 0xc) >> 2);
2201 		ext_lna = (gain & 2) >> 1;
2202 
2203 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
2204 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
2205 		    0xfbff, ext_lna << 10);
2206 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
2207 		    0xf7ff, ext_lna << 11);
2208 		BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, lna);
2209 	} else {
2210 		low_gain = gain & 0xffff;
2211 		high_gain = (gain >> 16) & 0xf;
2212 		ext_lna = (gain >> 21) & 0x1;
2213 		trsw = ~(gain >> 20) & 0x1;
2214 
2215 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0xfffe, trsw);
2216 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
2217 		    0xfdff, ext_lna << 9);
2218 		BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
2219 		    0xfbff, ext_lna << 10);
2220 		BWN_PHY_WRITE(mac, BWN_PHY_RX_GAIN_CTL_OVERRIDE_VAL, low_gain);
2221 		BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff0, high_gain);
2222 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
2223 			tmp = (gain >> 2) & 0x3;
2224 			BWN_PHY_SETMASK(mac, BWN_PHY_RF_OVERRIDE_2_VAL,
2225 			    0xe7ff, tmp<<11);
2226 			BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xe6), 0xffe7,
2227 			    tmp << 3);
2228 		}
2229 	}
2230 
2231 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x1);
2232 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x10);
2233 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x40);
2234 	if (mac->mac_phy.rev >= 2) {
2235 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
2236 		if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) {
2237 			BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x400);
2238 			BWN_PHY_SET(mac, BWN_PHY_OFDM(0xe5), 0x8);
2239 		}
2240 		return;
2241 	}
2242 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x200);
2243 }
2244 
2245 static void
2246 bwn_phy_lp_set_deaf(struct bwn_mac *mac, uint8_t user)
2247 {
2248 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
2249 
2250 	if (user)
2251 		plp->plp_crsusr_off = 1;
2252 	else
2253 		plp->plp_crssys_off = 1;
2254 
2255 	BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x80);
2256 }
2257 
2258 static void
2259 bwn_phy_lp_clear_deaf(struct bwn_mac *mac, uint8_t user)
2260 {
2261 	struct bwn_phy_lp *plp = &mac->mac_phy.phy_lp;
2262 	struct bwn_softc *sc = mac->mac_sc;
2263 	struct ieee80211com *ic = &sc->sc_ic;
2264 
2265 	if (user)
2266 		plp->plp_crsusr_off = 0;
2267 	else
2268 		plp->plp_crssys_off = 0;
2269 
2270 	if (plp->plp_crsusr_off || plp->plp_crssys_off)
2271 		return;
2272 
2273 	if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
2274 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x60);
2275 	else
2276 		BWN_PHY_SETMASK(mac, BWN_PHY_CRSGAIN_CTL, 0xff1f, 0x20);
2277 }
2278 
2279 static int
2280 bwn_phy_lp_calc_rx_iq_comp(struct bwn_mac *mac, uint16_t sample)
2281 {
2282 #define	CALC_COEFF(_v, _x, _y, _z)	do {				\
2283 	int _t;								\
2284 	_t = _x - 20;							\
2285 	if (_t >= 0) {							\
2286 		_v = ((_y << (30 - _x)) + (_z >> (1 + _t))) / (_z >> _t); \
2287 	} else {							\
2288 		_v = ((_y << (30 - _x)) + (_z << (-1 - _t))) / (_z << -_t); \
2289 	}								\
2290 } while (0)
2291 #define	CALC_COEFF2(_v, _x, _y, _z)	do {				\
2292 	int _t;								\
2293 	_t = _x - 11;							\
2294 	if (_t >= 0)							\
2295 		_v = (_y << (31 - _x)) / (_z >> _t);			\
2296 	else								\
2297 		_v = (_y << (31 - _x)) / (_z << -_t);			\
2298 } while (0)
2299 	struct bwn_phy_lp_iq_est ie;
2300 	uint16_t v0, v1;
2301 	int tmp[2], ret;
2302 
2303 	v1 = BWN_PHY_READ(mac, BWN_PHY_RX_COMP_COEFF_S);
2304 	v0 = v1 >> 8;
2305 	v1 |= 0xff;
2306 
2307 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, 0x00c0);
2308 	BWN_PHY_MASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff);
2309 
2310 	ret = bwn_phy_lp_rx_iq_est(mac, sample, 32, &ie);
2311 	if (ret == 0)
2312 		goto done;
2313 
2314 	if (ie.ie_ipwr + ie.ie_qpwr < 2) {
2315 		ret = 0;
2316 		goto done;
2317 	}
2318 
2319 	CALC_COEFF(tmp[0], bwn_nbits(ie.ie_iqprod), ie.ie_iqprod, ie.ie_ipwr);
2320 	CALC_COEFF2(tmp[1], bwn_nbits(ie.ie_qpwr), ie.ie_qpwr, ie.ie_ipwr);
2321 
2322 	tmp[1] = -bwn_sqrt(mac, tmp[1] - (tmp[0] * tmp[0]));
2323 	v0 = tmp[0] >> 3;
2324 	v1 = tmp[1] >> 4;
2325 done:
2326 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0xff00, v1);
2327 	BWN_PHY_SETMASK(mac, BWN_PHY_RX_COMP_COEFF_S, 0x00ff, v0 << 8);
2328 	return ret;
2329 #undef CALC_COEFF
2330 #undef CALC_COEFF2
2331 }
2332 
2333 static void
2334 bwn_phy_lp_tblinit_r01(struct bwn_mac *mac)
2335 {
2336 	static const uint16_t noisescale[] = {
2337 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
2338 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa400, 0xa4a4, 0xa4a4,
2339 		0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4, 0xa4a4,
2340 		0xa4a4, 0xa4a4, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2341 		0x0000, 0x0000, 0x4c00, 0x2d36, 0x0000, 0x0000, 0x4c00, 0x2d36,
2342 	};
2343 	static const uint16_t crsgainnft[] = {
2344 		0x0366, 0x036a, 0x036f, 0x0364, 0x0367, 0x036d, 0x0374, 0x037f,
2345 		0x036f, 0x037b, 0x038a, 0x0378, 0x0367, 0x036d, 0x0375, 0x0381,
2346 		0x0374, 0x0381, 0x0392, 0x03a9, 0x03c4, 0x03e1, 0x0001, 0x001f,
2347 		0x0040, 0x005e, 0x007f, 0x009e, 0x00bd, 0x00dd, 0x00fd, 0x011d,
2348 		0x013d,
2349 	};
2350 	static const uint16_t filterctl[] = {
2351 		0xa0fc, 0x10fc, 0x10db, 0x20b7, 0xff93, 0x10bf, 0x109b, 0x2077,
2352 		0xff53, 0x0127,
2353 	};
2354 	static const uint32_t psctl[] = {
2355 		0x00010000, 0x000000a0, 0x00040000, 0x00000048, 0x08080101,
2356 		0x00000080, 0x08080101, 0x00000040, 0x08080101, 0x000000c0,
2357 		0x08a81501, 0x000000c0, 0x0fe8fd01, 0x000000c0, 0x08300105,
2358 		0x000000c0, 0x08080201, 0x000000c0, 0x08280205, 0x000000c0,
2359 		0xe80802fe, 0x000000c7, 0x28080206, 0x000000c0, 0x08080202,
2360 		0x000000c0, 0x0ba87602, 0x000000c0, 0x1068013d, 0x000000c0,
2361 		0x10280105, 0x000000c0, 0x08880102, 0x000000c0, 0x08280106,
2362 		0x000000c0, 0xe80801fd, 0x000000c7, 0xa8080115, 0x000000c0,
2363 	};
2364 	static const uint16_t ofdmcckgain_r0[] = {
2365 		0x0001, 0x0001, 0x0001, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
2366 		0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
2367 		0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
2368 		0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
2369 		0x755d,
2370 	};
2371 	static const uint16_t ofdmcckgain_r1[] = {
2372 		0x5000, 0x6000, 0x7000, 0x0001, 0x1001, 0x2001, 0x3001, 0x4001,
2373 		0x5001, 0x6001, 0x7001, 0x7011, 0x7021, 0x2035, 0x2045, 0x2055,
2374 		0x2065, 0x2075, 0x006d, 0x007d, 0x014d, 0x015d, 0x115d, 0x035d,
2375 		0x135d, 0x055d, 0x155d, 0x0d5d, 0x1d5d, 0x2d5d, 0x555d, 0x655d,
2376 		0x755d,
2377 	};
2378 	static const uint16_t gaindelta[] = {
2379 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2380 		0x0000,
2381 	};
2382 	static const uint32_t txpwrctl[] = {
2383 		0x00000050, 0x0000004f, 0x0000004e, 0x0000004d, 0x0000004c,
2384 		0x0000004b, 0x0000004a, 0x00000049, 0x00000048, 0x00000047,
2385 		0x00000046, 0x00000045, 0x00000044, 0x00000043, 0x00000042,
2386 		0x00000041, 0x00000040, 0x0000003f, 0x0000003e, 0x0000003d,
2387 		0x0000003c, 0x0000003b, 0x0000003a, 0x00000039, 0x00000038,
2388 		0x00000037, 0x00000036, 0x00000035, 0x00000034, 0x00000033,
2389 		0x00000032, 0x00000031, 0x00000030, 0x0000002f, 0x0000002e,
2390 		0x0000002d, 0x0000002c, 0x0000002b, 0x0000002a, 0x00000029,
2391 		0x00000028, 0x00000027, 0x00000026, 0x00000025, 0x00000024,
2392 		0x00000023, 0x00000022, 0x00000021, 0x00000020, 0x0000001f,
2393 		0x0000001e, 0x0000001d, 0x0000001c, 0x0000001b, 0x0000001a,
2394 		0x00000019, 0x00000018, 0x00000017, 0x00000016, 0x00000015,
2395 		0x00000014, 0x00000013, 0x00000012, 0x00000011, 0x00000000,
2396 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2397 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2398 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2399 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2400 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2401 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2402 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2403 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2404 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2405 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2406 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2407 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2408 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2409 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2410 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2411 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2412 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2413 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2414 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2415 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2416 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2417 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2418 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2419 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2420 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2421 		0x00000000, 0x00000000, 0x000075a0, 0x000075a0, 0x000075a1,
2422 		0x000075a1, 0x000075a2, 0x000075a2, 0x000075a3, 0x000075a3,
2423 		0x000074b0, 0x000074b0, 0x000074b1, 0x000074b1, 0x000074b2,
2424 		0x000074b2, 0x000074b3, 0x000074b3, 0x00006d20, 0x00006d20,
2425 		0x00006d21, 0x00006d21, 0x00006d22, 0x00006d22, 0x00006d23,
2426 		0x00006d23, 0x00004660, 0x00004660, 0x00004661, 0x00004661,
2427 		0x00004662, 0x00004662, 0x00004663, 0x00004663, 0x00003e60,
2428 		0x00003e60, 0x00003e61, 0x00003e61, 0x00003e62, 0x00003e62,
2429 		0x00003e63, 0x00003e63, 0x00003660, 0x00003660, 0x00003661,
2430 		0x00003661, 0x00003662, 0x00003662, 0x00003663, 0x00003663,
2431 		0x00002e60, 0x00002e60, 0x00002e61, 0x00002e61, 0x00002e62,
2432 		0x00002e62, 0x00002e63, 0x00002e63, 0x00002660, 0x00002660,
2433 		0x00002661, 0x00002661, 0x00002662, 0x00002662, 0x00002663,
2434 		0x00002663, 0x000025e0, 0x000025e0, 0x000025e1, 0x000025e1,
2435 		0x000025e2, 0x000025e2, 0x000025e3, 0x000025e3, 0x00001de0,
2436 		0x00001de0, 0x00001de1, 0x00001de1, 0x00001de2, 0x00001de2,
2437 		0x00001de3, 0x00001de3, 0x00001d60, 0x00001d60, 0x00001d61,
2438 		0x00001d61, 0x00001d62, 0x00001d62, 0x00001d63, 0x00001d63,
2439 		0x00001560, 0x00001560, 0x00001561, 0x00001561, 0x00001562,
2440 		0x00001562, 0x00001563, 0x00001563, 0x00000d60, 0x00000d60,
2441 		0x00000d61, 0x00000d61, 0x00000d62, 0x00000d62, 0x00000d63,
2442 		0x00000d63, 0x00000ce0, 0x00000ce0, 0x00000ce1, 0x00000ce1,
2443 		0x00000ce2, 0x00000ce2, 0x00000ce3, 0x00000ce3, 0x00000e10,
2444 		0x00000e10, 0x00000e11, 0x00000e11, 0x00000e12, 0x00000e12,
2445 		0x00000e13, 0x00000e13, 0x00000bf0, 0x00000bf0, 0x00000bf1,
2446 		0x00000bf1, 0x00000bf2, 0x00000bf2, 0x00000bf3, 0x00000bf3,
2447 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
2448 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
2449 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
2450 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
2451 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
2452 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
2453 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
2454 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
2455 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
2456 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
2457 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
2458 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
2459 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
2460 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
2461 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
2462 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
2463 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
2464 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
2465 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
2466 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
2467 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
2468 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
2469 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
2470 		0x04000000, 0x04200000, 0x04000000, 0x04200000, 0x04000000,
2471 		0x04200000, 0x04000000, 0x04200000, 0x04000000, 0x04200000,
2472 		0x04000000, 0x04200000, 0x04000000, 0x000000ff, 0x000002fc,
2473 		0x0000fa08, 0x00000305, 0x00000206, 0x00000304, 0x0000fb04,
2474 		0x0000fcff, 0x000005fb, 0x0000fd01, 0x00000401, 0x00000006,
2475 		0x0000ff03, 0x000007fc, 0x0000fc08, 0x00000203, 0x0000fffb,
2476 		0x00000600, 0x0000fa01, 0x0000fc03, 0x0000fe06, 0x0000fe00,
2477 		0x00000102, 0x000007fd, 0x000004fb, 0x000006ff, 0x000004fd,
2478 		0x0000fdfa, 0x000007fb, 0x0000fdfa, 0x0000fa06, 0x00000500,
2479 		0x0000f902, 0x000007fa, 0x0000fafa, 0x00000500, 0x000007fa,
2480 		0x00000700, 0x00000305, 0x000004ff, 0x00000801, 0x00000503,
2481 		0x000005f9, 0x00000404, 0x0000fb08, 0x000005fd, 0x00000501,
2482 		0x00000405, 0x0000fb03, 0x000007fc, 0x00000403, 0x00000303,
2483 		0x00000402, 0x0000faff, 0x0000fe05, 0x000005fd, 0x0000fe01,
2484 		0x000007fa, 0x00000202, 0x00000504, 0x00000102, 0x000008fe,
2485 		0x0000fa04, 0x0000fafc, 0x0000fe08, 0x000000f9, 0x000002fa,
2486 		0x000003fe, 0x00000304, 0x000004f9, 0x00000100, 0x0000fd06,
2487 		0x000008fc, 0x00000701, 0x00000504, 0x0000fdfe, 0x0000fdfc,
2488 		0x000003fe, 0x00000704, 0x000002fc, 0x000004f9, 0x0000fdfd,
2489 		0x0000fa07, 0x00000205, 0x000003fd, 0x000005fb, 0x000004f9,
2490 		0x00000804, 0x0000fc06, 0x0000fcf9, 0x00000100, 0x0000fe05,
2491 		0x00000408, 0x0000fb02, 0x00000304, 0x000006fe, 0x000004fa,
2492 		0x00000305, 0x000008fc, 0x00000102, 0x000001fd, 0x000004fc,
2493 		0x0000fe03, 0x00000701, 0x000001fb, 0x000001f9, 0x00000206,
2494 		0x000006fd, 0x00000508, 0x00000700, 0x00000304, 0x000005fe,
2495 		0x000005ff, 0x0000fa04, 0x00000303, 0x0000fefb, 0x000007f9,
2496 		0x0000fefc, 0x000004fd, 0x000005fc, 0x0000fffd, 0x0000fc08,
2497 		0x0000fbf9, 0x0000fd07, 0x000008fb, 0x0000fe02, 0x000006fb,
2498 		0x00000702,
2499 	};
2500 
2501 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
2502 
2503 	bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
2504 	    bwn_tab_sigsq_tbl);
2505 	bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
2506 	bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(crsgainnft), crsgainnft);
2507 	bwn_tab_write_multi(mac, BWN_TAB_2(8, 0), N(filterctl), filterctl);
2508 	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(psctl), psctl);
2509 	bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
2510 	    bwn_tab_pllfrac_tbl);
2511 	bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
2512 	    bwn_tabl_iqlocal_tbl);
2513 	if (mac->mac_phy.rev == 0) {
2514 		bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r0),
2515 		    ofdmcckgain_r0);
2516 		bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r0),
2517 		    ofdmcckgain_r0);
2518 	} else {
2519 		bwn_tab_write_multi(mac, BWN_TAB_2(13, 0), N(ofdmcckgain_r1),
2520 		    ofdmcckgain_r1);
2521 		bwn_tab_write_multi(mac, BWN_TAB_2(12, 0), N(ofdmcckgain_r1),
2522 		    ofdmcckgain_r1);
2523 	}
2524 	bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(gaindelta), gaindelta);
2525 	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(txpwrctl), txpwrctl);
2526 }
2527 
2528 static void
2529 bwn_phy_lp_tblinit_r2(struct bwn_mac *mac)
2530 {
2531 	struct bwn_softc *sc = mac->mac_sc;
2532 	int i;
2533 	static const uint16_t noisescale[] = {
2534 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
2535 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
2536 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
2537 		0x00a4, 0x00a4, 0x0000, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
2538 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
2539 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4,
2540 		0x00a4, 0x00a4, 0x00a4, 0x00a4, 0x00a4
2541 	};
2542 	static const uint32_t filterctl[] = {
2543 		0x000141fc, 0x000021fc, 0x000021b7, 0x0000416f, 0x0001ff27,
2544 		0x0000217f, 0x00002137, 0x000040ef, 0x0001fea7, 0x0000024f
2545 	};
2546 	static const uint32_t psctl[] = {
2547 		0x00e38e08, 0x00e08e38, 0x00000000, 0x00000000, 0x00000000,
2548 		0x00002080, 0x00006180, 0x00003002, 0x00000040, 0x00002042,
2549 		0x00180047, 0x00080043, 0x00000041, 0x000020c1, 0x00046006,
2550 		0x00042002, 0x00040000, 0x00002003, 0x00180006, 0x00080002
2551 	};
2552 	static const uint32_t gainidx[] = {
2553 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2554 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2555 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2556 		0x00000000, 0x00000000, 0x00000000, 0x10000001, 0x00000000,
2557 		0x20000082, 0x00000000, 0x40000104, 0x00000000, 0x60004207,
2558 		0x00000001, 0x7000838a, 0x00000001, 0xd021050d, 0x00000001,
2559 		0xe041c683, 0x00000001, 0x50828805, 0x00000000, 0x80e34288,
2560 		0x00000000, 0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000,
2561 		0x12064711, 0x00000001, 0xb0a18612, 0x00000010, 0xe1024794,
2562 		0x00000010, 0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011,
2563 		0xc1848a9c, 0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21,
2564 		0x00000019, 0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019,
2565 		0xb36811a6, 0x00000019, 0xf3e89227, 0x00000019, 0x0408d329,
2566 		0x0000001a, 0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a,
2567 		0x54aa152c, 0x0000001a, 0x64ca55ad, 0x0000001a, 0x00000000,
2568 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2569 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2570 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2571 		0x00000000, 0x00000000, 0x10000001, 0x00000000, 0x20000082,
2572 		0x00000000, 0x40000104, 0x00000000, 0x60004207, 0x00000001,
2573 		0x7000838a, 0x00000001, 0xd021050d, 0x00000001, 0xe041c683,
2574 		0x00000001, 0x50828805, 0x00000000, 0x80e34288, 0x00000000,
2575 		0xb144040b, 0x00000000, 0xe1a6058e, 0x00000000, 0x12064711,
2576 		0x00000001, 0xb0a18612, 0x00000010, 0xe1024794, 0x00000010,
2577 		0x11630915, 0x00000011, 0x31c3ca1b, 0x00000011, 0xc1848a9c,
2578 		0x00000018, 0xf1e50da0, 0x00000018, 0x22468e21, 0x00000019,
2579 		0x4286d023, 0x00000019, 0xa347d0a4, 0x00000019, 0xb36811a6,
2580 		0x00000019, 0xf3e89227, 0x00000019, 0x0408d329, 0x0000001a,
2581 		0x244953aa, 0x0000001a, 0x346994ab, 0x0000001a, 0x54aa152c,
2582 		0x0000001a, 0x64ca55ad, 0x0000001a
2583 	};
2584 	static const uint16_t auxgainidx[] = {
2585 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2586 		0x0000, 0x0001, 0x0002, 0x0004, 0x0016, 0x0000, 0x0000, 0x0000,
2587 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002,
2588 		0x0004, 0x0016
2589 	};
2590 	static const uint16_t swctl[] = {
2591 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
2592 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
2593 		0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
2594 		0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018,
2595 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
2596 		0x0128, 0x0128, 0x0009, 0x0009, 0x0028, 0x0028, 0x0028, 0x0028,
2597 		0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009, 0x0009,
2598 		0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018, 0x0018
2599 	};
2600 	static const uint8_t hf[] = {
2601 		0x4b, 0x36, 0x24, 0x18, 0x49, 0x34, 0x23, 0x17, 0x48,
2602 		0x33, 0x23, 0x17, 0x48, 0x33, 0x23, 0x17
2603 	};
2604 	static const uint32_t gainval[] = {
2605 		0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
2606 		0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
2607 		0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
2608 		0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
2609 		0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
2610 		0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
2611 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2612 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2613 		0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
2614 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
2615 		0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
2616 		0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
2617 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009,
2618 		0x000000f1, 0x00000000, 0x00000000
2619 	};
2620 	static const uint16_t gain[] = {
2621 		0x0000, 0x0400, 0x0800, 0x0802, 0x0804, 0x0806, 0x0807, 0x0808,
2622 		0x080a, 0x080b, 0x080c, 0x080e, 0x080f, 0x0810, 0x0812, 0x0813,
2623 		0x0814, 0x0816, 0x0817, 0x081a, 0x081b, 0x081f, 0x0820, 0x0824,
2624 		0x0830, 0x0834, 0x0837, 0x083b, 0x083f, 0x0840, 0x0844, 0x0857,
2625 		0x085b, 0x085f, 0x08d7, 0x08db, 0x08df, 0x0957, 0x095b, 0x095f,
2626 		0x0b57, 0x0b5b, 0x0b5f, 0x0f5f, 0x135f, 0x175f, 0x0000, 0x0000,
2627 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2628 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2629 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2630 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2631 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2632 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
2633 	};
2634 	static const uint32_t papdeps[] = {
2635 		0x00000000, 0x00013ffc, 0x0001dff3, 0x0001bff0, 0x00023fe9,
2636 		0x00021fdf, 0x00028fdf, 0x00033fd2, 0x00039fcb, 0x00043fc7,
2637 		0x0004efc2, 0x00055fb5, 0x0005cfb0, 0x00063fa8, 0x00068fa3,
2638 		0x00071f98, 0x0007ef92, 0x00084f8b, 0x0008df82, 0x00097f77,
2639 		0x0009df69, 0x000a3f62, 0x000adf57, 0x000b6f4c, 0x000bff41,
2640 		0x000c9f39, 0x000cff30, 0x000dbf27, 0x000e4f1e, 0x000edf16,
2641 		0x000f7f13, 0x00102f11, 0x00110f10, 0x0011df11, 0x0012ef15,
2642 		0x00143f1c, 0x00158f27, 0x00172f35, 0x00193f47, 0x001baf5f,
2643 		0x001e6f7e, 0x0021cfa4, 0x0025bfd2, 0x002a2008, 0x002fb047,
2644 		0x00360090, 0x003d40e0, 0x0045c135, 0x004fb189, 0x005ae1d7,
2645 		0x0067221d, 0x0075025a, 0x007ff291, 0x007ff2bf, 0x007ff2e3,
2646 		0x007ff2ff, 0x007ff315, 0x007ff329, 0x007ff33f, 0x007ff356,
2647 		0x007ff36e, 0x007ff39c, 0x007ff441, 0x007ff506
2648 	};
2649 	static const uint32_t papdmult[] = {
2650 		0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
2651 		0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
2652 		0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
2653 		0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
2654 		0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
2655 		0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
2656 		0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
2657 		0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
2658 		0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
2659 		0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
2660 		0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
2661 		0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
2662 		0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
2663 	};
2664 	static const uint32_t gainidx_a0[] = {
2665 		0x001111e0, 0x00652051, 0x00606055, 0x005b005a, 0x00555060,
2666 		0x00511065, 0x004c806b, 0x0047d072, 0x00444078, 0x00400080,
2667 		0x003ca087, 0x0039408f, 0x0035e098, 0x0032e0a1, 0x003030aa,
2668 		0x002d80b4, 0x002ae0bf, 0x002880ca, 0x002640d6, 0x002410e3,
2669 		0x002220f0, 0x002020ff, 0x001e510e, 0x001ca11e, 0x001b012f,
2670 		0x00199140, 0x00182153, 0x0016c168, 0x0015817d, 0x00145193,
2671 		0x001321ab, 0x001211c5, 0x001111e0, 0x001021fc, 0x000f321a,
2672 		0x000e523a, 0x000d925c, 0x000cd27f, 0x000c12a5, 0x000b62cd,
2673 		0x000ac2f8, 0x000a2325, 0x00099355, 0x00091387, 0x000883bd,
2674 		0x000813f5, 0x0007a432, 0x00073471, 0x0006c4b5, 0x000664fc,
2675 		0x00061547, 0x0005b598, 0x000565ec, 0x00051646, 0x0004d6a5,
2676 		0x0004870a, 0x00044775, 0x000407e6, 0x0003d85e, 0x000398dd,
2677 		0x00036963, 0x000339f2, 0x00030a89, 0x0002db28
2678 	};
2679 	static const uint16_t auxgainidx_a0[] = {
2680 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2681 		0x0000, 0x0000, 0x0000, 0x0002, 0x0014, 0x0000, 0x0000, 0x0000,
2682 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2683 		0x0002, 0x0014
2684 	};
2685 	static const uint32_t gainval_a0[] = {
2686 		0x00000008, 0x0000000e, 0x00000014, 0x0000001a, 0x000000fb,
2687 		0x00000004, 0x00000008, 0x0000000d, 0x00000001, 0x00000004,
2688 		0x00000007, 0x0000000a, 0x0000000d, 0x00000010, 0x00000012,
2689 		0x00000015, 0x00000000, 0x00000006, 0x0000000c, 0x00000000,
2690 		0x00000000, 0x00000000, 0x00000012, 0x00000000, 0x00000000,
2691 		0x00000000, 0x00000018, 0x00000000, 0x00000000, 0x00000000,
2692 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2693 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2694 		0x00000000, 0x00000000, 0x0000001e, 0x00000000, 0x00000000,
2695 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000003,
2696 		0x00000006, 0x00000009, 0x0000000c, 0x0000000f, 0x00000012,
2697 		0x00000015, 0x00000018, 0x0000001b, 0x0000001e, 0x00000000,
2698 		0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x0000000f,
2699 		0x000000f7, 0x00000000, 0x00000000
2700 	};
2701 	static const uint16_t gain_a0[] = {
2702 		0x0000, 0x0002, 0x0004, 0x0006, 0x0007, 0x0008, 0x000a, 0x000b,
2703 		0x000c, 0x000e, 0x000f, 0x0010, 0x0012, 0x0013, 0x0014, 0x0016,
2704 		0x0017, 0x001a, 0x001b, 0x001f, 0x0020, 0x0024, 0x0030, 0x0034,
2705 		0x0037, 0x003b, 0x003f, 0x0040, 0x0044, 0x0057, 0x005b, 0x005f,
2706 		0x00d7, 0x00db, 0x00df, 0x0157, 0x015b, 0x015f, 0x0357, 0x035b,
2707 		0x035f, 0x075f, 0x0b5f, 0x0f5f, 0x0000, 0x0000, 0x0000, 0x0000,
2708 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2709 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2710 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2711 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2712 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2713 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
2714 	};
2715 
2716 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
2717 
2718 	for (i = 0; i < 704; i++)
2719 		bwn_tab_write(mac, BWN_TAB_4(7, i), 0);
2720 
2721 	bwn_tab_write_multi(mac, BWN_TAB_1(2, 0), N(bwn_tab_sigsq_tbl),
2722 	    bwn_tab_sigsq_tbl);
2723 	bwn_tab_write_multi(mac, BWN_TAB_2(1, 0), N(noisescale), noisescale);
2724 	bwn_tab_write_multi(mac, BWN_TAB_4(11, 0), N(filterctl), filterctl);
2725 	bwn_tab_write_multi(mac, BWN_TAB_4(12, 0), N(psctl), psctl);
2726 	bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx), gainidx);
2727 	bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx), auxgainidx);
2728 	bwn_tab_write_multi(mac, BWN_TAB_2(15, 0), N(swctl), swctl);
2729 	bwn_tab_write_multi(mac, BWN_TAB_1(16, 0), N(hf), hf);
2730 	bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval), gainval);
2731 	bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain), gain);
2732 	bwn_tab_write_multi(mac, BWN_TAB_1(6, 0), N(bwn_tab_pllfrac_tbl),
2733 	    bwn_tab_pllfrac_tbl);
2734 	bwn_tab_write_multi(mac, BWN_TAB_2(0, 0), N(bwn_tabl_iqlocal_tbl),
2735 	    bwn_tabl_iqlocal_tbl);
2736 	bwn_tab_write_multi(mac, BWN_TAB_4(9, 0), N(papdeps), papdeps);
2737 	bwn_tab_write_multi(mac, BWN_TAB_4(10, 0), N(papdmult), papdmult);
2738 
2739 	if ((siba_get_chipid(sc->sc_dev) == 0x4325) &&
2740 	    (siba_get_chiprev(sc->sc_dev) == 0)) {
2741 		bwn_tab_write_multi(mac, BWN_TAB_4(13, 0), N(gainidx_a0),
2742 		    gainidx_a0);
2743 		bwn_tab_write_multi(mac, BWN_TAB_2(14, 0), N(auxgainidx_a0),
2744 		    auxgainidx_a0);
2745 		bwn_tab_write_multi(mac, BWN_TAB_4(17, 0), N(gainval_a0),
2746 		    gainval_a0);
2747 		bwn_tab_write_multi(mac, BWN_TAB_2(18, 0), N(gain_a0), gain_a0);
2748 	}
2749 }
2750 
2751 static void
2752 bwn_phy_lp_tblinit_txgain(struct bwn_mac *mac)
2753 {
2754 	struct bwn_softc *sc = mac->mac_sc;
2755 	struct ieee80211com *ic = &sc->sc_ic;
2756 	static struct bwn_txgain_entry txgain_r2[] = {
2757 		{ 255, 255, 203, 0, 152 }, { 255, 255, 203, 0, 147 },
2758 		{ 255, 255, 203, 0, 143 }, { 255, 255, 203, 0, 139 },
2759 		{ 255, 255, 203, 0, 135 }, { 255, 255, 203, 0, 131 },
2760 		{ 255, 255, 203, 0, 128 }, { 255, 255, 203, 0, 124 },
2761 		{ 255, 255, 203, 0, 121 }, { 255, 255, 203, 0, 117 },
2762 		{ 255, 255, 203, 0, 114 }, { 255, 255, 203, 0, 111 },
2763 		{ 255, 255, 203, 0, 107 }, { 255, 255, 203, 0, 104 },
2764 		{ 255, 255, 203, 0, 101 }, { 255, 255, 203, 0, 99 },
2765 		{ 255, 255, 203, 0, 96 }, { 255, 255, 203, 0, 93 },
2766 		{ 255, 255, 203, 0, 90 }, { 255, 255, 203, 0, 88 },
2767 		{ 255, 255, 203, 0, 85 }, { 255, 255, 203, 0, 83 },
2768 		{ 255, 255, 203, 0, 81 }, { 255, 255, 203, 0, 78 },
2769 		{ 255, 255, 203, 0, 76 }, { 255, 255, 203, 0, 74 },
2770 		{ 255, 255, 203, 0, 72 }, { 255, 255, 203, 0, 70 },
2771 		{ 255, 255, 203, 0, 68 }, { 255, 255, 203, 0, 66 },
2772 		{ 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
2773 		{ 255, 255, 192, 0, 64 }, { 255, 255, 186, 0, 64 },
2774 		{ 255, 255, 181, 0, 64 }, { 255, 255, 176, 0, 64 },
2775 		{ 255, 255, 171, 0, 64 }, { 255, 255, 166, 0, 64 },
2776 		{ 255, 255, 161, 0, 64 }, { 255, 255, 157, 0, 64 },
2777 		{ 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
2778 		{ 255, 255, 144, 0, 64 }, { 255, 255, 140, 0, 64 },
2779 		{ 255, 255, 136, 0, 64 }, { 255, 255, 132, 0, 64 },
2780 		{ 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
2781 		{ 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
2782 		{ 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
2783 		{ 255, 255, 108, 0, 64 }, { 255, 255, 105, 0, 64 },
2784 		{ 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
2785 		{ 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
2786 		{ 255, 255, 91, 0, 64 }, { 255, 255, 88, 0, 64 },
2787 		{ 255, 255, 86, 0, 64 }, { 255, 255, 83, 0, 64 },
2788 		{ 255, 255, 81, 0, 64 }, { 255, 255, 79, 0, 64 },
2789 		{ 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
2790 		{ 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
2791 		{ 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
2792 		{ 255, 255, 64, 0, 64 }, { 255, 248, 64, 0, 64 },
2793 		{ 255, 248, 62, 0, 64 }, { 255, 241, 62, 0, 64 },
2794 		{ 255, 241, 60, 0, 64 }, { 255, 234, 60, 0, 64 },
2795 		{ 255, 234, 59, 0, 64 }, { 255, 227, 59, 0, 64 },
2796 		{ 255, 227, 57, 0, 64 }, { 255, 221, 57, 0, 64 },
2797 		{ 255, 221, 55, 0, 64 }, { 255, 215, 55, 0, 64 },
2798 		{ 255, 215, 54, 0, 64 }, { 255, 208, 54, 0, 64 },
2799 		{ 255, 208, 52, 0, 64 }, { 255, 203, 52, 0, 64 },
2800 		{ 255, 203, 51, 0, 64 }, { 255, 197, 51, 0, 64 },
2801 		{ 255, 197, 49, 0, 64 }, { 255, 191, 49, 0, 64 },
2802 		{ 255, 191, 48, 0, 64 }, { 255, 186, 48, 0, 64 },
2803 		{ 255, 186, 47, 0, 64 }, { 255, 181, 47, 0, 64 },
2804 		{ 255, 181, 45, 0, 64 }, { 255, 175, 45, 0, 64 },
2805 		{ 255, 175, 44, 0, 64 }, { 255, 170, 44, 0, 64 },
2806 		{ 255, 170, 43, 0, 64 }, { 255, 166, 43, 0, 64 },
2807 		{ 255, 166, 42, 0, 64 }, { 255, 161, 42, 0, 64 },
2808 		{ 255, 161, 40, 0, 64 }, { 255, 156, 40, 0, 64 },
2809 		{ 255, 156, 39, 0, 64 }, { 255, 152, 39, 0, 64 },
2810 		{ 255, 152, 38, 0, 64 }, { 255, 148, 38, 0, 64 },
2811 		{ 255, 148, 37, 0, 64 }, { 255, 143, 37, 0, 64 },
2812 		{ 255, 143, 36, 0, 64 }, { 255, 139, 36, 0, 64 },
2813 		{ 255, 139, 35, 0, 64 }, { 255, 135, 35, 0, 64 },
2814 		{ 255, 135, 34, 0, 64 }, { 255, 132, 34, 0, 64 },
2815 		{ 255, 132, 33, 0, 64 }, { 255, 128, 33, 0, 64 },
2816 		{ 255, 128, 32, 0, 64 }, { 255, 124, 32, 0, 64 },
2817 		{ 255, 124, 31, 0, 64 }, { 255, 121, 31, 0, 64 },
2818 		{ 255, 121, 30, 0, 64 }, { 255, 117, 30, 0, 64 },
2819 		{ 255, 117, 29, 0, 64 }, { 255, 114, 29, 0, 64 },
2820 		{ 255, 114, 29, 0, 64 }, { 255, 111, 29, 0, 64 },
2821 	};
2822 	static struct bwn_txgain_entry txgain_2ghz_r2[] = {
2823 		{ 7, 99, 255, 0, 64 }, { 7, 96, 255, 0, 64 },
2824 		{ 7, 93, 255, 0, 64 }, { 7, 90, 255, 0, 64 },
2825 		{ 7, 88, 255, 0, 64 }, { 7, 85, 255, 0, 64 },
2826 		{ 7, 83, 255, 0, 64 }, { 7, 81, 255, 0, 64 },
2827 		{ 7, 78, 255, 0, 64 }, { 7, 76, 255, 0, 64 },
2828 		{ 7, 74, 255, 0, 64 }, { 7, 72, 255, 0, 64 },
2829 		{ 7, 70, 255, 0, 64 }, { 7, 68, 255, 0, 64 },
2830 		{ 7, 66, 255, 0, 64 }, { 7, 64, 255, 0, 64 },
2831 		{ 7, 64, 255, 0, 64 }, { 7, 62, 255, 0, 64 },
2832 		{ 7, 62, 248, 0, 64 }, { 7, 60, 248, 0, 64 },
2833 		{ 7, 60, 241, 0, 64 }, { 7, 59, 241, 0, 64 },
2834 		{ 7, 59, 234, 0, 64 }, { 7, 57, 234, 0, 64 },
2835 		{ 7, 57, 227, 0, 64 }, { 7, 55, 227, 0, 64 },
2836 		{ 7, 55, 221, 0, 64 }, { 7, 54, 221, 0, 64 },
2837 		{ 7, 54, 215, 0, 64 }, { 7, 52, 215, 0, 64 },
2838 		{ 7, 52, 208, 0, 64 }, { 7, 51, 208, 0, 64 },
2839 		{ 7, 51, 203, 0, 64 }, { 7, 49, 203, 0, 64 },
2840 		{ 7, 49, 197, 0, 64 }, { 7, 48, 197, 0, 64 },
2841 		{ 7, 48, 191, 0, 64 }, { 7, 47, 191, 0, 64 },
2842 		{ 7, 47, 186, 0, 64 }, { 7, 45, 186, 0, 64 },
2843 		{ 7, 45, 181, 0, 64 }, { 7, 44, 181, 0, 64 },
2844 		{ 7, 44, 175, 0, 64 }, { 7, 43, 175, 0, 64 },
2845 		{ 7, 43, 170, 0, 64 }, { 7, 42, 170, 0, 64 },
2846 		{ 7, 42, 166, 0, 64 }, { 7, 40, 166, 0, 64 },
2847 		{ 7, 40, 161, 0, 64 }, { 7, 39, 161, 0, 64 },
2848 		{ 7, 39, 156, 0, 64 }, { 7, 38, 156, 0, 64 },
2849 		{ 7, 38, 152, 0, 64 }, { 7, 37, 152, 0, 64 },
2850 		{ 7, 37, 148, 0, 64 }, { 7, 36, 148, 0, 64 },
2851 		{ 7, 36, 143, 0, 64 }, { 7, 35, 143, 0, 64 },
2852 		{ 7, 35, 139, 0, 64 }, { 7, 34, 139, 0, 64 },
2853 		{ 7, 34, 135, 0, 64 }, { 7, 33, 135, 0, 64 },
2854 		{ 7, 33, 132, 0, 64 }, { 7, 32, 132, 0, 64 },
2855 		{ 7, 32, 128, 0, 64 }, { 7, 31, 128, 0, 64 },
2856 		{ 7, 31, 124, 0, 64 }, { 7, 30, 124, 0, 64 },
2857 		{ 7, 30, 121, 0, 64 }, { 7, 29, 121, 0, 64 },
2858 		{ 7, 29, 117, 0, 64 }, { 7, 29, 117, 0, 64 },
2859 		{ 7, 29, 114, 0, 64 }, { 7, 28, 114, 0, 64 },
2860 		{ 7, 28, 111, 0, 64 }, { 7, 27, 111, 0, 64 },
2861 		{ 7, 27, 108, 0, 64 }, { 7, 26, 108, 0, 64 },
2862 		{ 7, 26, 104, 0, 64 }, { 7, 25, 104, 0, 64 },
2863 		{ 7, 25, 102, 0, 64 }, { 7, 25, 102, 0, 64 },
2864 		{ 7, 25, 99, 0, 64 }, { 7, 24, 99, 0, 64 },
2865 		{ 7, 24, 96, 0, 64 }, { 7, 23, 96, 0, 64 },
2866 		{ 7, 23, 93, 0, 64 }, { 7, 23, 93, 0, 64 },
2867 		{ 7, 23, 90, 0, 64 }, { 7, 22, 90, 0, 64 },
2868 		{ 7, 22, 88, 0, 64 }, { 7, 21, 88, 0, 64 },
2869 		{ 7, 21, 85, 0, 64 }, { 7, 21, 85, 0, 64 },
2870 		{ 7, 21, 83, 0, 64 }, { 7, 20, 83, 0, 64 },
2871 		{ 7, 20, 81, 0, 64 }, { 7, 20, 81, 0, 64 },
2872 		{ 7, 20, 78, 0, 64 }, { 7, 19, 78, 0, 64 },
2873 		{ 7, 19, 76, 0, 64 }, { 7, 19, 76, 0, 64 },
2874 		{ 7, 19, 74, 0, 64 }, { 7, 18, 74, 0, 64 },
2875 		{ 7, 18, 72, 0, 64 }, { 7, 18, 72, 0, 64 },
2876 		{ 7, 18, 70, 0, 64 }, { 7, 17, 70, 0, 64 },
2877 		{ 7, 17, 68, 0, 64 }, { 7, 17, 68, 0, 64 },
2878 		{ 7, 17, 66, 0, 64 }, { 7, 16, 66, 0, 64 },
2879 		{ 7, 16, 64, 0, 64 }, { 7, 16, 64, 0, 64 },
2880 		{ 7, 16, 62, 0, 64 }, { 7, 15, 62, 0, 64 },
2881 		{ 7, 15, 60, 0, 64 }, { 7, 15, 60, 0, 64 },
2882 		{ 7, 15, 59, 0, 64 }, { 7, 14, 59, 0, 64 },
2883 		{ 7, 14, 57, 0, 64 }, { 7, 14, 57, 0, 64 },
2884 		{ 7, 14, 55, 0, 64 }, { 7, 14, 55, 0, 64 },
2885 		{ 7, 14, 54, 0, 64 }, { 7, 13, 54, 0, 64 },
2886 		{ 7, 13, 52, 0, 64 }, { 7, 13, 52, 0, 64 },
2887 	};
2888 	static struct bwn_txgain_entry txgain_5ghz_r2[] = {
2889 		{ 255, 255, 255, 0, 152 }, { 255, 255, 255, 0, 147 },
2890 		{ 255, 255, 255, 0, 143 }, { 255, 255, 255, 0, 139 },
2891 		{ 255, 255, 255, 0, 135 }, { 255, 255, 255, 0, 131 },
2892 		{ 255, 255, 255, 0, 128 }, { 255, 255, 255, 0, 124 },
2893 		{ 255, 255, 255, 0, 121 }, { 255, 255, 255, 0, 117 },
2894 		{ 255, 255, 255, 0, 114 }, { 255, 255, 255, 0, 111 },
2895 		{ 255, 255, 255, 0, 107 }, { 255, 255, 255, 0, 104 },
2896 		{ 255, 255, 255, 0, 101 }, { 255, 255, 255, 0, 99 },
2897 		{ 255, 255, 255, 0, 96 }, { 255, 255, 255, 0, 93 },
2898 		{ 255, 255, 255, 0, 90 }, { 255, 255, 255, 0, 88 },
2899 		{ 255, 255, 255, 0, 85 }, { 255, 255, 255, 0, 83 },
2900 		{ 255, 255, 255, 0, 81 }, { 255, 255, 255, 0, 78 },
2901 		{ 255, 255, 255, 0, 76 }, { 255, 255, 255, 0, 74 },
2902 		{ 255, 255, 255, 0, 72 }, { 255, 255, 255, 0, 70 },
2903 		{ 255, 255, 255, 0, 68 }, { 255, 255, 255, 0, 66 },
2904 		{ 255, 255, 255, 0, 64 }, { 255, 255, 248, 0, 64 },
2905 		{ 255, 255, 241, 0, 64 }, { 255, 255, 234, 0, 64 },
2906 		{ 255, 255, 227, 0, 64 }, { 255, 255, 221, 0, 64 },
2907 		{ 255, 255, 215, 0, 64 }, { 255, 255, 208, 0, 64 },
2908 		{ 255, 255, 203, 0, 64 }, { 255, 255, 197, 0, 64 },
2909 		{ 255, 255, 191, 0, 64 }, { 255, 255, 186, 0, 64 },
2910 		{ 255, 255, 181, 0, 64 }, { 255, 255, 175, 0, 64 },
2911 		{ 255, 255, 170, 0, 64 }, { 255, 255, 166, 0, 64 },
2912 		{ 255, 255, 161, 0, 64 }, { 255, 255, 156, 0, 64 },
2913 		{ 255, 255, 152, 0, 64 }, { 255, 255, 148, 0, 64 },
2914 		{ 255, 255, 143, 0, 64 }, { 255, 255, 139, 0, 64 },
2915 		{ 255, 255, 135, 0, 64 }, { 255, 255, 132, 0, 64 },
2916 		{ 255, 255, 128, 0, 64 }, { 255, 255, 124, 0, 64 },
2917 		{ 255, 255, 121, 0, 64 }, { 255, 255, 117, 0, 64 },
2918 		{ 255, 255, 114, 0, 64 }, { 255, 255, 111, 0, 64 },
2919 		{ 255, 255, 108, 0, 64 }, { 255, 255, 104, 0, 64 },
2920 		{ 255, 255, 102, 0, 64 }, { 255, 255, 99, 0, 64 },
2921 		{ 255, 255, 96, 0, 64 }, { 255, 255, 93, 0, 64 },
2922 		{ 255, 255, 90, 0, 64 }, { 255, 255, 88, 0, 64 },
2923 		{ 255, 255, 85, 0, 64 }, { 255, 255, 83, 0, 64 },
2924 		{ 255, 255, 81, 0, 64 }, { 255, 255, 78, 0, 64 },
2925 		{ 255, 255, 76, 0, 64 }, { 255, 255, 74, 0, 64 },
2926 		{ 255, 255, 72, 0, 64 }, { 255, 255, 70, 0, 64 },
2927 		{ 255, 255, 68, 0, 64 }, { 255, 255, 66, 0, 64 },
2928 		{ 255, 255, 64, 0, 64 }, { 255, 255, 64, 0, 64 },
2929 		{ 255, 255, 62, 0, 64 }, { 255, 248, 62, 0, 64 },
2930 		{ 255, 248, 60, 0, 64 }, { 255, 241, 60, 0, 64 },
2931 		{ 255, 241, 59, 0, 64 }, { 255, 234, 59, 0, 64 },
2932 		{ 255, 234, 57, 0, 64 }, { 255, 227, 57, 0, 64 },
2933 		{ 255, 227, 55, 0, 64 }, { 255, 221, 55, 0, 64 },
2934 		{ 255, 221, 54, 0, 64 }, { 255, 215, 54, 0, 64 },
2935 		{ 255, 215, 52, 0, 64 }, { 255, 208, 52, 0, 64 },
2936 		{ 255, 208, 51, 0, 64 }, { 255, 203, 51, 0, 64 },
2937 		{ 255, 203, 49, 0, 64 }, { 255, 197, 49, 0, 64 },
2938 		{ 255, 197, 48, 0, 64 }, { 255, 191, 48, 0, 64 },
2939 		{ 255, 191, 47, 0, 64 }, { 255, 186, 47, 0, 64 },
2940 		{ 255, 186, 45, 0, 64 }, { 255, 181, 45, 0, 64 },
2941 		{ 255, 181, 44, 0, 64 }, { 255, 175, 44, 0, 64 },
2942 		{ 255, 175, 43, 0, 64 }, { 255, 170, 43, 0, 64 },
2943 		{ 255, 170, 42, 0, 64 }, { 255, 166, 42, 0, 64 },
2944 		{ 255, 166, 40, 0, 64 }, { 255, 161, 40, 0, 64 },
2945 		{ 255, 161, 39, 0, 64 }, { 255, 156, 39, 0, 64 },
2946 		{ 255, 156, 38, 0, 64 }, { 255, 152, 38, 0, 64 },
2947 		{ 255, 152, 37, 0, 64 }, { 255, 148, 37, 0, 64 },
2948 		{ 255, 148, 36, 0, 64 }, { 255, 143, 36, 0, 64 },
2949 		{ 255, 143, 35, 0, 64 }, { 255, 139, 35, 0, 64 },
2950 		{ 255, 139, 34, 0, 64 }, { 255, 135, 34, 0, 64 },
2951 		{ 255, 135, 33, 0, 64 }, { 255, 132, 33, 0, 64 },
2952 		{ 255, 132, 32, 0, 64 }, { 255, 128, 32, 0, 64 }
2953 	};
2954 	static struct bwn_txgain_entry txgain_r0[] = {
2955 		{ 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
2956 		{ 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
2957 		{ 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
2958 		{ 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
2959 		{ 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
2960 		{ 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
2961 		{ 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
2962 		{ 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
2963 		{ 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
2964 		{ 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
2965 		{ 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
2966 		{ 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
2967 		{ 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
2968 		{ 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
2969 		{ 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
2970 		{ 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
2971 		{ 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
2972 		{ 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
2973 		{ 7, 15, 13, 0, 70 }, { 7, 15, 13, 0, 68 },
2974 		{ 7, 15, 13, 0, 66 }, { 7, 15, 13, 0, 64 },
2975 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
2976 		{ 7, 15, 13, 0, 59 }, { 7, 15, 13, 0, 57 },
2977 		{ 7, 15, 12, 0, 71 }, { 7, 15, 12, 0, 69 },
2978 		{ 7, 15, 12, 0, 67 }, { 7, 15, 12, 0, 65 },
2979 		{ 7, 15, 12, 0, 63 }, { 7, 15, 12, 0, 62 },
2980 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 58 },
2981 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 70 },
2982 		{ 7, 15, 11, 0, 68 }, { 7, 15, 11, 0, 66 },
2983 		{ 7, 15, 11, 0, 65 }, { 7, 15, 11, 0, 63 },
2984 		{ 7, 15, 11, 0, 61 }, { 7, 15, 11, 0, 59 },
2985 		{ 7, 15, 11, 0, 58 }, { 7, 15, 10, 0, 71 },
2986 		{ 7, 15, 10, 0, 69 }, { 7, 15, 10, 0, 67 },
2987 		{ 7, 15, 10, 0, 65 }, { 7, 15, 10, 0, 63 },
2988 		{ 7, 15, 10, 0, 61 }, { 7, 15, 10, 0, 60 },
2989 		{ 7, 15, 10, 0, 58 }, { 7, 15, 10, 0, 56 },
2990 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
2991 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
2992 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 60 },
2993 		{ 7, 15, 9, 0, 59 }, { 7, 14, 9, 0, 72 },
2994 		{ 7, 14, 9, 0, 70 }, { 7, 14, 9, 0, 68 },
2995 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 64 },
2996 		{ 7, 14, 9, 0, 62 }, { 7, 14, 9, 0, 60 },
2997 		{ 7, 14, 9, 0, 59 }, { 7, 13, 9, 0, 72 },
2998 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
2999 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
3000 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
3001 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
3002 		{ 7, 13, 8, 0, 72 }, { 7, 13, 8, 0, 70 },
3003 		{ 7, 13, 8, 0, 68 }, { 7, 13, 8, 0, 66 },
3004 		{ 7, 13, 8, 0, 64 }, { 7, 13, 8, 0, 62 },
3005 		{ 7, 13, 8, 0, 60 }, { 7, 13, 8, 0, 59 },
3006 		{ 7, 12, 8, 0, 72 }, { 7, 12, 8, 0, 70 },
3007 		{ 7, 12, 8, 0, 68 }, { 7, 12, 8, 0, 66 },
3008 		{ 7, 12, 8, 0, 64 }, { 7, 12, 8, 0, 62 },
3009 		{ 7, 12, 8, 0, 61 }, { 7, 12, 8, 0, 59 },
3010 		{ 7, 12, 7, 0, 73 }, { 7, 12, 7, 0, 71 },
3011 		{ 7, 12, 7, 0, 69 }, { 7, 12, 7, 0, 67 },
3012 		{ 7, 12, 7, 0, 65 }, { 7, 12, 7, 0, 63 },
3013 		{ 7, 12, 7, 0, 61 }, { 7, 12, 7, 0, 59 },
3014 		{ 7, 11, 7, 0, 72 }, { 7, 11, 7, 0, 70 },
3015 		{ 7, 11, 7, 0, 68 }, { 7, 11, 7, 0, 66 },
3016 		{ 7, 11, 7, 0, 65 }, { 7, 11, 7, 0, 63 },
3017 		{ 7, 11, 7, 0, 61 }, { 7, 11, 7, 0, 59 },
3018 		{ 7, 11, 6, 0, 73 }, { 7, 11, 6, 0, 71 }
3019 	};
3020 	static struct bwn_txgain_entry txgain_2ghz_r0[] = {
3021 		{ 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
3022 		{ 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
3023 		{ 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
3024 		{ 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
3025 		{ 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
3026 		{ 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
3027 		{ 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
3028 		{ 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
3029 		{ 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
3030 		{ 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
3031 		{ 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
3032 		{ 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
3033 		{ 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
3034 		{ 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
3035 		{ 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
3036 		{ 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
3037 		{ 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
3038 		{ 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
3039 		{ 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
3040 		{ 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
3041 		{ 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
3042 		{ 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
3043 		{ 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
3044 		{ 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
3045 		{ 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
3046 		{ 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
3047 		{ 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
3048 		{ 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
3049 		{ 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
3050 		{ 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
3051 		{ 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
3052 		{ 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
3053 		{ 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
3054 		{ 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 },
3055 		{ 4, 10, 6, 0, 59 }, { 4, 10, 5, 0, 72 },
3056 		{ 4, 10, 5, 0, 70 }, { 4, 10, 5, 0, 68 },
3057 		{ 4, 10, 5, 0, 66 }, { 4, 10, 5, 0, 64 },
3058 		{ 4, 10, 5, 0, 62 }, { 4, 10, 5, 0, 60 },
3059 		{ 4, 10, 5, 0, 59 }, { 4, 9, 5, 0, 70 },
3060 		{ 4, 9, 5, 0, 68 }, { 4, 9, 5, 0, 66 },
3061 		{ 4, 9, 5, 0, 64 }, { 4, 9, 5, 0, 63 },
3062 		{ 4, 9, 5, 0, 61 }, { 4, 9, 5, 0, 59 },
3063 		{ 4, 9, 4, 0, 71 }, { 4, 9, 4, 0, 69 },
3064 		{ 4, 9, 4, 0, 67 }, { 4, 9, 4, 0, 65 },
3065 		{ 4, 9, 4, 0, 63 }, { 4, 9, 4, 0, 62 },
3066 		{ 4, 9, 4, 0, 60 }, { 4, 9, 4, 0, 58 },
3067 		{ 4, 8, 4, 0, 70 }, { 4, 8, 4, 0, 68 },
3068 		{ 4, 8, 4, 0, 66 }, { 4, 8, 4, 0, 65 },
3069 		{ 4, 8, 4, 0, 63 }, { 4, 8, 4, 0, 61 },
3070 		{ 4, 8, 4, 0, 59 }, { 4, 7, 4, 0, 68 },
3071 		{ 4, 7, 4, 0, 66 }, { 4, 7, 4, 0, 64 },
3072 		{ 4, 7, 4, 0, 62 }, { 4, 7, 4, 0, 61 },
3073 		{ 4, 7, 4, 0, 59 }, { 4, 7, 3, 0, 67 },
3074 		{ 4, 7, 3, 0, 65 }, { 4, 7, 3, 0, 63 },
3075 		{ 4, 7, 3, 0, 62 }, { 4, 7, 3, 0, 60 },
3076 		{ 4, 6, 3, 0, 65 }, { 4, 6, 3, 0, 63 },
3077 		{ 4, 6, 3, 0, 61 }, { 4, 6, 3, 0, 60 },
3078 		{ 4, 6, 3, 0, 58 }, { 4, 5, 3, 0, 68 },
3079 		{ 4, 5, 3, 0, 66 }, { 4, 5, 3, 0, 64 },
3080 		{ 4, 5, 3, 0, 62 }, { 4, 5, 3, 0, 60 },
3081 		{ 4, 5, 3, 0, 59 }, { 4, 5, 3, 0, 57 },
3082 		{ 4, 4, 2, 0, 83 }, { 4, 4, 2, 0, 81 },
3083 		{ 4, 4, 2, 0, 78 }, { 4, 4, 2, 0, 76 },
3084 		{ 4, 4, 2, 0, 74 }, { 4, 4, 2, 0, 72 }
3085 	};
3086 	static struct bwn_txgain_entry txgain_5ghz_r0[] = {
3087 		{ 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
3088 		{ 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
3089 		{ 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
3090 		{ 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
3091 		{ 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
3092 		{ 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
3093 		{ 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
3094 		{ 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
3095 		{ 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
3096 		{ 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
3097 		{ 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
3098 		{ 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
3099 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
3100 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
3101 		{ 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
3102 		{ 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
3103 		{ 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
3104 		{ 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
3105 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
3106 		{ 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
3107 		{ 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
3108 		{ 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
3109 		{ 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
3110 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
3111 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
3112 		{ 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
3113 		{ 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
3114 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
3115 		{ 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
3116 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
3117 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
3118 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
3119 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
3120 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
3121 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
3122 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
3123 		{ 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
3124 		{ 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
3125 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
3126 		{ 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
3127 		{ 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
3128 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
3129 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
3130 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
3131 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
3132 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
3133 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
3134 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
3135 		{ 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
3136 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
3137 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
3138 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
3139 		{ 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
3140 		{ 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
3141 		{ 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
3142 		{ 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
3143 		{ 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
3144 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
3145 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
3146 		{ 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
3147 		{ 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
3148 		{ 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
3149 		{ 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
3150 		{ 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
3151 	};
3152 	static struct bwn_txgain_entry txgain_r1[] = {
3153 		{ 7, 15, 14, 0, 152 }, { 7, 15, 14, 0, 147 },
3154 		{ 7, 15, 14, 0, 143 }, { 7, 15, 14, 0, 139 },
3155 		{ 7, 15, 14, 0, 135 }, { 7, 15, 14, 0, 131 },
3156 		{ 7, 15, 14, 0, 128 }, { 7, 15, 14, 0, 124 },
3157 		{ 7, 15, 14, 0, 121 }, { 7, 15, 14, 0, 117 },
3158 		{ 7, 15, 14, 0, 114 }, { 7, 15, 14, 0, 111 },
3159 		{ 7, 15, 14, 0, 107 }, { 7, 15, 14, 0, 104 },
3160 		{ 7, 15, 14, 0, 101 }, { 7, 15, 14, 0, 99 },
3161 		{ 7, 15, 14, 0, 96 }, { 7, 15, 14, 0, 93 },
3162 		{ 7, 15, 14, 0, 90 }, { 7, 15, 14, 0, 88 },
3163 		{ 7, 15, 14, 0, 85 }, { 7, 15, 14, 0, 83 },
3164 		{ 7, 15, 14, 0, 81 }, { 7, 15, 14, 0, 78 },
3165 		{ 7, 15, 14, 0, 76 }, { 7, 15, 14, 0, 74 },
3166 		{ 7, 15, 14, 0, 72 }, { 7, 15, 14, 0, 70 },
3167 		{ 7, 15, 14, 0, 68 }, { 7, 15, 14, 0, 66 },
3168 		{ 7, 15, 14, 0, 64 }, { 7, 15, 14, 0, 62 },
3169 		{ 7, 15, 14, 0, 60 }, { 7, 15, 14, 0, 59 },
3170 		{ 7, 15, 14, 0, 57 }, { 7, 15, 13, 0, 72 },
3171 		{ 7, 15, 13, 0, 70 }, { 7, 15, 14, 0, 68 },
3172 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
3173 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
3174 		{ 7, 15, 14, 0, 59 }, { 7, 15, 14, 0, 57 },
3175 		{ 7, 15, 13, 0, 72 }, { 7, 15, 13, 0, 70 },
3176 		{ 7, 15, 13, 0, 68 }, { 7, 15, 13, 0, 66 },
3177 		{ 7, 15, 13, 0, 64 }, { 7, 15, 13, 0, 62 },
3178 		{ 7, 15, 13, 0, 60 }, { 7, 15, 13, 0, 59 },
3179 		{ 7, 15, 13, 0, 57 }, { 7, 15, 12, 0, 71 },
3180 		{ 7, 15, 12, 0, 69 }, { 7, 15, 12, 0, 67 },
3181 		{ 7, 15, 12, 0, 65 }, { 7, 15, 12, 0, 63 },
3182 		{ 7, 15, 12, 0, 62 }, { 7, 15, 12, 0, 60 },
3183 		{ 7, 15, 12, 0, 58 }, { 7, 15, 12, 0, 57 },
3184 		{ 7, 15, 11, 0, 70 }, { 7, 15, 11, 0, 68 },
3185 		{ 7, 15, 11, 0, 66 }, { 7, 15, 11, 0, 65 },
3186 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
3187 		{ 7, 15, 11, 0, 59 }, { 7, 15, 11, 0, 58 },
3188 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
3189 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
3190 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
3191 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
3192 		{ 7, 15, 10, 0, 56 }, { 7, 15, 9, 0, 70 },
3193 		{ 7, 15, 9, 0, 68 }, { 7, 15, 9, 0, 66 },
3194 		{ 7, 15, 9, 0, 64 }, { 7, 15, 9, 0, 62 },
3195 		{ 7, 15, 9, 0, 60 }, { 7, 15, 9, 0, 59 },
3196 		{ 7, 14, 9, 0, 72 }, { 7, 14, 9, 0, 70 },
3197 		{ 7, 14, 9, 0, 68 }, { 7, 14, 9, 0, 66 },
3198 		{ 7, 14, 9, 0, 64 }, { 7, 14, 9, 0, 62 },
3199 		{ 7, 14, 9, 0, 60 }, { 7, 14, 9, 0, 59 },
3200 		{ 7, 13, 9, 0, 72 }, { 7, 13, 9, 0, 70 },
3201 		{ 7, 13, 9, 0, 68 }, { 7, 13, 9, 0, 66 },
3202 		{ 7, 13, 9, 0, 64 }, { 7, 13, 9, 0, 63 },
3203 		{ 7, 13, 9, 0, 61 }, { 7, 13, 9, 0, 59 },
3204 		{ 7, 13, 9, 0, 57 }, { 7, 13, 8, 0, 72 },
3205 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
3206 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
3207 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
3208 		{ 7, 13, 8, 0, 59 }, { 7, 12, 8, 0, 72 },
3209 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
3210 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
3211 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
3212 		{ 7, 12, 8, 0, 59 }, { 7, 12, 7, 0, 73 },
3213 		{ 7, 12, 7, 0, 71 }, { 7, 12, 7, 0, 69 },
3214 		{ 7, 12, 7, 0, 67 }, { 7, 12, 7, 0, 65 },
3215 		{ 7, 12, 7, 0, 63 }, { 7, 12, 7, 0, 61 },
3216 		{ 7, 12, 7, 0, 59 }, { 7, 11, 7, 0, 72 },
3217 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
3218 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 65 },
3219 		{ 7, 11, 7, 0, 63 }, { 7, 11, 7, 0, 61 },
3220 		{ 7, 11, 7, 0, 59 }, { 7, 11, 6, 0, 73 },
3221 		{ 7, 11, 6, 0, 71 }
3222 	};
3223 	static struct bwn_txgain_entry txgain_2ghz_r1[] = {
3224 		{ 4, 15, 15, 0, 90 }, { 4, 15, 15, 0, 88 },
3225 		{ 4, 15, 15, 0, 85 }, { 4, 15, 15, 0, 83 },
3226 		{ 4, 15, 15, 0, 81 }, { 4, 15, 15, 0, 78 },
3227 		{ 4, 15, 15, 0, 76 }, { 4, 15, 15, 0, 74 },
3228 		{ 4, 15, 15, 0, 72 }, { 4, 15, 15, 0, 70 },
3229 		{ 4, 15, 15, 0, 68 }, { 4, 15, 15, 0, 66 },
3230 		{ 4, 15, 15, 0, 64 }, { 4, 15, 15, 0, 62 },
3231 		{ 4, 15, 15, 0, 60 }, { 4, 15, 15, 0, 59 },
3232 		{ 4, 15, 14, 0, 72 }, { 4, 15, 14, 0, 70 },
3233 		{ 4, 15, 14, 0, 68 }, { 4, 15, 14, 0, 66 },
3234 		{ 4, 15, 14, 0, 64 }, { 4, 15, 14, 0, 62 },
3235 		{ 4, 15, 14, 0, 60 }, { 4, 15, 14, 0, 59 },
3236 		{ 4, 15, 13, 0, 72 }, { 4, 15, 13, 0, 70 },
3237 		{ 4, 15, 13, 0, 68 }, { 4, 15, 13, 0, 66 },
3238 		{ 4, 15, 13, 0, 64 }, { 4, 15, 13, 0, 62 },
3239 		{ 4, 15, 13, 0, 60 }, { 4, 15, 13, 0, 59 },
3240 		{ 4, 15, 12, 0, 72 }, { 4, 15, 12, 0, 70 },
3241 		{ 4, 15, 12, 0, 68 }, { 4, 15, 12, 0, 66 },
3242 		{ 4, 15, 12, 0, 64 }, { 4, 15, 12, 0, 62 },
3243 		{ 4, 15, 12, 0, 60 }, { 4, 15, 12, 0, 59 },
3244 		{ 4, 15, 11, 0, 72 }, { 4, 15, 11, 0, 70 },
3245 		{ 4, 15, 11, 0, 68 }, { 4, 15, 11, 0, 66 },
3246 		{ 4, 15, 11, 0, 64 }, { 4, 15, 11, 0, 62 },
3247 		{ 4, 15, 11, 0, 60 }, { 4, 15, 11, 0, 59 },
3248 		{ 4, 15, 10, 0, 72 }, { 4, 15, 10, 0, 70 },
3249 		{ 4, 15, 10, 0, 68 }, { 4, 15, 10, 0, 66 },
3250 		{ 4, 15, 10, 0, 64 }, { 4, 15, 10, 0, 62 },
3251 		{ 4, 15, 10, 0, 60 }, { 4, 15, 10, 0, 59 },
3252 		{ 4, 15, 9, 0, 72 }, { 4, 15, 9, 0, 70 },
3253 		{ 4, 15, 9, 0, 68 }, { 4, 15, 9, 0, 66 },
3254 		{ 4, 15, 9, 0, 64 }, { 4, 15, 9, 0, 62 },
3255 		{ 4, 15, 9, 0, 60 }, { 4, 15, 9, 0, 59 },
3256 		{ 4, 14, 9, 0, 72 }, { 4, 14, 9, 0, 70 },
3257 		{ 4, 14, 9, 0, 68 }, { 4, 14, 9, 0, 66 },
3258 		{ 4, 14, 9, 0, 64 }, { 4, 14, 9, 0, 62 },
3259 		{ 4, 14, 9, 0, 60 }, { 4, 14, 9, 0, 59 },
3260 		{ 4, 13, 9, 0, 72 }, { 4, 13, 9, 0, 70 },
3261 		{ 4, 13, 9, 0, 68 }, { 4, 13, 9, 0, 66 },
3262 		{ 4, 13, 9, 0, 64 }, { 4, 13, 9, 0, 63 },
3263 		{ 4, 13, 9, 0, 61 }, { 4, 13, 9, 0, 59 },
3264 		{ 4, 13, 9, 0, 57 }, { 4, 13, 8, 0, 72 },
3265 		{ 4, 13, 8, 0, 70 }, { 4, 13, 8, 0, 68 },
3266 		{ 4, 13, 8, 0, 66 }, { 4, 13, 8, 0, 64 },
3267 		{ 4, 13, 8, 0, 62 }, { 4, 13, 8, 0, 60 },
3268 		{ 4, 13, 8, 0, 59 }, { 4, 12, 8, 0, 72 },
3269 		{ 4, 12, 8, 0, 70 }, { 4, 12, 8, 0, 68 },
3270 		{ 4, 12, 8, 0, 66 }, { 4, 12, 8, 0, 64 },
3271 		{ 4, 12, 8, 0, 62 }, { 4, 12, 8, 0, 61 },
3272 		{ 4, 12, 8, 0, 59 }, { 4, 12, 7, 0, 73 },
3273 		{ 4, 12, 7, 0, 71 }, { 4, 12, 7, 0, 69 },
3274 		{ 4, 12, 7, 0, 67 }, { 4, 12, 7, 0, 65 },
3275 		{ 4, 12, 7, 0, 63 }, { 4, 12, 7, 0, 61 },
3276 		{ 4, 12, 7, 0, 59 }, { 4, 11, 7, 0, 72 },
3277 		{ 4, 11, 7, 0, 70 }, { 4, 11, 7, 0, 68 },
3278 		{ 4, 11, 7, 0, 66 }, { 4, 11, 7, 0, 65 },
3279 		{ 4, 11, 7, 0, 63 }, { 4, 11, 7, 0, 61 },
3280 		{ 4, 11, 7, 0, 59 }, { 4, 11, 6, 0, 73 },
3281 		{ 4, 11, 6, 0, 71 }, { 4, 11, 6, 0, 69 },
3282 		{ 4, 11, 6, 0, 67 }, { 4, 11, 6, 0, 65 },
3283 		{ 4, 11, 6, 0, 63 }, { 4, 11, 6, 0, 61 },
3284 		{ 4, 11, 6, 0, 60 }, { 4, 10, 6, 0, 72 },
3285 		{ 4, 10, 6, 0, 70 }, { 4, 10, 6, 0, 68 },
3286 		{ 4, 10, 6, 0, 66 }, { 4, 10, 6, 0, 64 },
3287 		{ 4, 10, 6, 0, 62 }, { 4, 10, 6, 0, 60 }
3288 	};
3289 	static struct bwn_txgain_entry txgain_5ghz_r1[] = {
3290 		{ 7, 15, 15, 0, 99 }, { 7, 15, 15, 0, 96 },
3291 		{ 7, 15, 15, 0, 93 }, { 7, 15, 15, 0, 90 },
3292 		{ 7, 15, 15, 0, 88 }, { 7, 15, 15, 0, 85 },
3293 		{ 7, 15, 15, 0, 83 }, { 7, 15, 15, 0, 81 },
3294 		{ 7, 15, 15, 0, 78 }, { 7, 15, 15, 0, 76 },
3295 		{ 7, 15, 15, 0, 74 }, { 7, 15, 15, 0, 72 },
3296 		{ 7, 15, 15, 0, 70 }, { 7, 15, 15, 0, 68 },
3297 		{ 7, 15, 15, 0, 66 }, { 7, 15, 15, 0, 64 },
3298 		{ 7, 15, 15, 0, 62 }, { 7, 15, 15, 0, 60 },
3299 		{ 7, 15, 15, 0, 59 }, { 7, 15, 15, 0, 57 },
3300 		{ 7, 15, 15, 0, 55 }, { 7, 15, 14, 0, 72 },
3301 		{ 7, 15, 14, 0, 70 }, { 7, 15, 14, 0, 68 },
3302 		{ 7, 15, 14, 0, 66 }, { 7, 15, 14, 0, 64 },
3303 		{ 7, 15, 14, 0, 62 }, { 7, 15, 14, 0, 60 },
3304 		{ 7, 15, 14, 0, 58 }, { 7, 15, 14, 0, 56 },
3305 		{ 7, 15, 14, 0, 55 }, { 7, 15, 13, 0, 71 },
3306 		{ 7, 15, 13, 0, 69 }, { 7, 15, 13, 0, 67 },
3307 		{ 7, 15, 13, 0, 65 }, { 7, 15, 13, 0, 63 },
3308 		{ 7, 15, 13, 0, 62 }, { 7, 15, 13, 0, 60 },
3309 		{ 7, 15, 13, 0, 58 }, { 7, 15, 13, 0, 56 },
3310 		{ 7, 15, 12, 0, 72 }, { 7, 15, 12, 0, 70 },
3311 		{ 7, 15, 12, 0, 68 }, { 7, 15, 12, 0, 66 },
3312 		{ 7, 15, 12, 0, 64 }, { 7, 15, 12, 0, 62 },
3313 		{ 7, 15, 12, 0, 60 }, { 7, 15, 12, 0, 59 },
3314 		{ 7, 15, 12, 0, 57 }, { 7, 15, 11, 0, 73 },
3315 		{ 7, 15, 11, 0, 71 }, { 7, 15, 11, 0, 69 },
3316 		{ 7, 15, 11, 0, 67 }, { 7, 15, 11, 0, 65 },
3317 		{ 7, 15, 11, 0, 63 }, { 7, 15, 11, 0, 61 },
3318 		{ 7, 15, 11, 0, 60 }, { 7, 15, 11, 0, 58 },
3319 		{ 7, 15, 10, 0, 71 }, { 7, 15, 10, 0, 69 },
3320 		{ 7, 15, 10, 0, 67 }, { 7, 15, 10, 0, 65 },
3321 		{ 7, 15, 10, 0, 63 }, { 7, 15, 10, 0, 61 },
3322 		{ 7, 15, 10, 0, 60 }, { 7, 15, 10, 0, 58 },
3323 		{ 7, 15, 9, 0, 70 }, { 7, 15, 9, 0, 68 },
3324 		{ 7, 15, 9, 0, 66 }, { 7, 15, 9, 0, 64 },
3325 		{ 7, 15, 9, 0, 62 }, { 7, 15, 9, 0, 61 },
3326 		{ 7, 15, 9, 0, 59 }, { 7, 15, 9, 0, 57 },
3327 		{ 7, 15, 9, 0, 56 }, { 7, 14, 9, 0, 68 },
3328 		{ 7, 14, 9, 0, 66 }, { 7, 14, 9, 0, 65 },
3329 		{ 7, 14, 9, 0, 63 }, { 7, 14, 9, 0, 61 },
3330 		{ 7, 14, 9, 0, 59 }, { 7, 14, 9, 0, 58 },
3331 		{ 7, 13, 9, 0, 70 }, { 7, 13, 9, 0, 68 },
3332 		{ 7, 13, 9, 0, 66 }, { 7, 13, 9, 0, 64 },
3333 		{ 7, 13, 9, 0, 63 }, { 7, 13, 9, 0, 61 },
3334 		{ 7, 13, 9, 0, 59 }, { 7, 13, 9, 0, 57 },
3335 		{ 7, 13, 8, 0, 70 }, { 7, 13, 8, 0, 68 },
3336 		{ 7, 13, 8, 0, 66 }, { 7, 13, 8, 0, 64 },
3337 		{ 7, 13, 8, 0, 62 }, { 7, 13, 8, 0, 60 },
3338 		{ 7, 13, 8, 0, 59 }, { 7, 13, 8, 0, 57 },
3339 		{ 7, 12, 8, 0, 70 }, { 7, 12, 8, 0, 68 },
3340 		{ 7, 12, 8, 0, 66 }, { 7, 12, 8, 0, 64 },
3341 		{ 7, 12, 8, 0, 62 }, { 7, 12, 8, 0, 61 },
3342 		{ 7, 12, 8, 0, 59 }, { 7, 12, 8, 0, 57 },
3343 		{ 7, 12, 7, 0, 70 }, { 7, 12, 7, 0, 68 },
3344 		{ 7, 12, 7, 0, 66 }, { 7, 12, 7, 0, 64 },
3345 		{ 7, 12, 7, 0, 62 }, { 7, 12, 7, 0, 61 },
3346 		{ 7, 12, 7, 0, 59 }, { 7, 12, 7, 0, 57 },
3347 		{ 7, 11, 7, 0, 70 }, { 7, 11, 7, 0, 68 },
3348 		{ 7, 11, 7, 0, 66 }, { 7, 11, 7, 0, 64 },
3349 		{ 7, 11, 7, 0, 62 }, { 7, 11, 7, 0, 61 },
3350 		{ 7, 11, 7, 0, 59 }, { 7, 11, 7, 0, 57 },
3351 		{ 7, 11, 6, 0, 69 }, { 7, 11, 6, 0, 67 },
3352 		{ 7, 11, 6, 0, 65 }, { 7, 11, 6, 0, 63 },
3353 		{ 7, 11, 6, 0, 62 }, { 7, 11, 6, 0, 60 }
3354 	};
3355 
3356 	if (mac->mac_phy.rev != 0 && mac->mac_phy.rev != 1) {
3357 		if (siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA)
3358 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r2);
3359 		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
3360 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
3361 			    txgain_2ghz_r2);
3362 		else
3363 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
3364 			    txgain_5ghz_r2);
3365 		return;
3366 	}
3367 
3368 	if (mac->mac_phy.rev == 0) {
3369 		if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
3370 		    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
3371 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r0);
3372 		else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
3373 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
3374 			    txgain_2ghz_r0);
3375 		else
3376 			bwn_phy_lp_gaintbl_write_multi(mac, 0, 128,
3377 			    txgain_5ghz_r0);
3378 		return;
3379 	}
3380 
3381 	if ((siba_sprom_get_bf_hi(sc->sc_dev) & BWN_BFH_NOPA) ||
3382 	    (siba_sprom_get_bf_lo(sc->sc_dev) & BWN_BFL_HGPA))
3383 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_r1);
3384 	else if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan))
3385 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_2ghz_r1);
3386 	else
3387 		bwn_phy_lp_gaintbl_write_multi(mac, 0, 128, txgain_5ghz_r1);
3388 }
3389 
3390 static void
3391 bwn_tab_write(struct bwn_mac *mac, uint32_t typeoffset, uint32_t value)
3392 {
3393 	uint32_t offset, type;
3394 
3395 	type = BWN_TAB_GETTYPE(typeoffset);
3396 	offset = BWN_TAB_GETOFFSET(typeoffset);
3397 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
3398 
3399 	switch (type) {
3400 	case BWN_TAB_8BIT:
3401 		KASSERT(!(value & ~0xff), ("%s:%d: fail", __func__, __LINE__));
3402 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
3403 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
3404 		break;
3405 	case BWN_TAB_16BIT:
3406 		KASSERT(!(value & ~0xffff),
3407 		    ("%s:%d: fail", __func__, __LINE__));
3408 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
3409 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
3410 		break;
3411 	case BWN_TAB_32BIT:
3412 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
3413 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATAHI, value >> 16);
3414 		BWN_PHY_WRITE(mac, BWN_PHY_TABLEDATALO, value);
3415 		break;
3416 	default:
3417 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3418 	}
3419 }
3420 
3421 static int
3422 bwn_phy_lp_loopback(struct bwn_mac *mac)
3423 {
3424 	struct bwn_phy_lp_iq_est ie;
3425 	int i, index = -1;
3426 	uint32_t tmp;
3427 
3428 	memset(&ie, 0, sizeof(ie));
3429 
3430 	bwn_phy_lp_set_trsw_over(mac, 1, 1);
3431 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 1);
3432 	BWN_PHY_MASK(mac, BWN_PHY_AFE_CTL_OVRVAL, 0xfffe);
3433 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x800);
3434 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x800);
3435 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x8);
3436 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x8);
3437 	BWN_RF_WRITE(mac, BWN_B2062_N_TXCTL_A, 0x80);
3438 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_0, 0x80);
3439 	BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_VAL_0, 0x80);
3440 	for (i = 0; i < 32; i++) {
3441 		bwn_phy_lp_set_rxgain_idx(mac, i);
3442 		bwn_phy_lp_ddfs_turnon(mac, 1, 1, 5, 5, 0);
3443 		if (!(bwn_phy_lp_rx_iq_est(mac, 1000, 32, &ie)))
3444 			continue;
3445 		tmp = (ie.ie_ipwr + ie.ie_qpwr) / 1000;
3446 		if ((tmp > 4000) && (tmp < 10000)) {
3447 			index = i;
3448 			break;
3449 		}
3450 	}
3451 	bwn_phy_lp_ddfs_turnoff(mac);
3452 	return (index);
3453 }
3454 
3455 static void
3456 bwn_phy_lp_set_rxgain_idx(struct bwn_mac *mac, uint16_t idx)
3457 {
3458 
3459 	bwn_phy_lp_set_rxgain(mac, bwn_tab_read(mac, BWN_TAB_2(12, idx)));
3460 }
3461 
3462 static void
3463 bwn_phy_lp_ddfs_turnon(struct bwn_mac *mac, int i_on, int q_on,
3464     int incr1, int incr2, int scale_idx)
3465 {
3466 
3467 	bwn_phy_lp_ddfs_turnoff(mac);
3468 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0xff80);
3469 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS_POINTER_INIT, 0x80ff);
3470 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0xff80, incr1);
3471 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS_INCR_INIT, 0x80ff, incr2 << 8);
3472 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xfff7, i_on << 3);
3473 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xffef, q_on << 4);
3474 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DDFS, 0xff9f, scale_idx << 5);
3475 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffb);
3476 	BWN_PHY_SET(mac, BWN_PHY_AFE_DDFS, 0x2);
3477 	BWN_PHY_SET(mac, BWN_PHY_LP_PHY_CTL, 0x20);
3478 }
3479 
3480 static uint8_t
3481 bwn_phy_lp_rx_iq_est(struct bwn_mac *mac, uint16_t sample, uint8_t time,
3482     struct bwn_phy_lp_iq_est *ie)
3483 {
3484 	int i;
3485 
3486 	BWN_PHY_MASK(mac, BWN_PHY_CRSGAIN_CTL, 0xfff7);
3487 	BWN_PHY_WRITE(mac, BWN_PHY_IQ_NUM_SMPLS_ADDR, sample);
3488 	BWN_PHY_SETMASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xff00, time);
3489 	BWN_PHY_MASK(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0xfeff);
3490 	BWN_PHY_SET(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR, 0x200);
3491 
3492 	for (i = 0; i < 500; i++) {
3493 		if (!(BWN_PHY_READ(mac,
3494 		    BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200))
3495 			break;
3496 		DELAY(1000);
3497 	}
3498 	if ((BWN_PHY_READ(mac, BWN_PHY_IQ_ENABLE_WAIT_TIME_ADDR) & 0x200)) {
3499 		BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
3500 		return 0;
3501 	}
3502 
3503 	ie->ie_iqprod = BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_HI_ADDR);
3504 	ie->ie_iqprod <<= 16;
3505 	ie->ie_iqprod |= BWN_PHY_READ(mac, BWN_PHY_IQ_ACC_LO_ADDR);
3506 	ie->ie_ipwr = BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_HI_ADDR);
3507 	ie->ie_ipwr <<= 16;
3508 	ie->ie_ipwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_I_PWR_ACC_LO_ADDR);
3509 	ie->ie_qpwr = BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_HI_ADDR);
3510 	ie->ie_qpwr <<= 16;
3511 	ie->ie_qpwr |= BWN_PHY_READ(mac, BWN_PHY_IQ_Q_PWR_ACC_LO_ADDR);
3512 
3513 	BWN_PHY_SET(mac, BWN_PHY_CRSGAIN_CTL, 0x8);
3514 	return 1;
3515 }
3516 
3517 static uint32_t
3518 bwn_tab_read(struct bwn_mac *mac, uint32_t typeoffset)
3519 {
3520 	uint32_t offset, type, value;
3521 
3522 	type = BWN_TAB_GETTYPE(typeoffset);
3523 	offset = BWN_TAB_GETOFFSET(typeoffset);
3524 	KASSERT(offset <= 0xffff, ("%s:%d: fail", __func__, __LINE__));
3525 
3526 	switch (type) {
3527 	case BWN_TAB_8BIT:
3528 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
3529 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO) & 0xff;
3530 		break;
3531 	case BWN_TAB_16BIT:
3532 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
3533 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
3534 		break;
3535 	case BWN_TAB_32BIT:
3536 		BWN_PHY_WRITE(mac, BWN_PHY_TABLE_ADDR, offset);
3537 		value = BWN_PHY_READ(mac, BWN_PHY_TABLEDATAHI);
3538 		value <<= 16;
3539 		value |= BWN_PHY_READ(mac, BWN_PHY_TABLEDATALO);
3540 		break;
3541 	default:
3542 		KASSERT(0 == 1, ("%s:%d: fail", __func__, __LINE__));
3543 		value = 0;
3544 	}
3545 
3546 	return (value);
3547 }
3548 
3549 static void
3550 bwn_phy_lp_ddfs_turnoff(struct bwn_mac *mac)
3551 {
3552 
3553 	BWN_PHY_MASK(mac, BWN_PHY_AFE_DDFS, 0xfffd);
3554 	BWN_PHY_MASK(mac, BWN_PHY_LP_PHY_CTL, 0xffdf);
3555 }
3556 
3557 static void
3558 bwn_phy_lp_set_txgain_dac(struct bwn_mac *mac, uint16_t dac)
3559 {
3560 	uint16_t ctl;
3561 
3562 	ctl = BWN_PHY_READ(mac, BWN_PHY_AFE_DAC_CTL) & 0xc7f;
3563 	ctl |= dac << 7;
3564 	BWN_PHY_SETMASK(mac, BWN_PHY_AFE_DAC_CTL, 0xf000, ctl);
3565 }
3566 
3567 static void
3568 bwn_phy_lp_set_txgain_pa(struct bwn_mac *mac, uint16_t gain)
3569 {
3570 
3571 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfb), 0xe03f, gain << 6);
3572 	BWN_PHY_SETMASK(mac, BWN_PHY_OFDM(0xfd), 0x80ff, gain << 8);
3573 }
3574 
3575 static void
3576 bwn_phy_lp_set_txgain_override(struct bwn_mac *mac)
3577 {
3578 
3579 	if (mac->mac_phy.rev < 2)
3580 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x100);
3581 	else {
3582 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x80);
3583 		BWN_PHY_SET(mac, BWN_PHY_RF_OVERRIDE_2, 0x4000);
3584 	}
3585 	BWN_PHY_SET(mac, BWN_PHY_AFE_CTL_OVR, 0x40);
3586 }
3587 
3588 static uint16_t
3589 bwn_phy_lp_get_pa_gain(struct bwn_mac *mac)
3590 {
3591 
3592 	return BWN_PHY_READ(mac, BWN_PHY_OFDM(0xfb)) & 0x7f;
3593 }
3594 
3595 static uint8_t
3596 bwn_nbits(int32_t val)
3597 {
3598 	uint32_t tmp;
3599 	uint8_t nbits = 0;
3600 
3601 	for (tmp = abs(val); tmp != 0; tmp >>= 1)
3602 		nbits++;
3603 	return (nbits);
3604 }
3605 
3606 static void
3607 bwn_phy_lp_gaintbl_write_multi(struct bwn_mac *mac, int offset, int count,
3608     struct bwn_txgain_entry *table)
3609 {
3610 	int i;
3611 
3612 	for (i = offset; i < count; i++)
3613 		bwn_phy_lp_gaintbl_write(mac, i, table[i]);
3614 }
3615 
3616 static void
3617 bwn_phy_lp_gaintbl_write(struct bwn_mac *mac, int offset,
3618     struct bwn_txgain_entry data)
3619 {
3620 
3621 	if (mac->mac_phy.rev >= 2)
3622 		bwn_phy_lp_gaintbl_write_r2(mac, offset, data);
3623 	else
3624 		bwn_phy_lp_gaintbl_write_r01(mac, offset, data);
3625 }
3626 
3627 static void
3628 bwn_phy_lp_gaintbl_write_r2(struct bwn_mac *mac, int offset,
3629     struct bwn_txgain_entry te)
3630 {
3631 	struct bwn_softc *sc = mac->mac_sc;
3632 	struct ieee80211com *ic = &sc->sc_ic;
3633 	uint32_t tmp;
3634 
3635 	KASSERT(mac->mac_phy.rev >= 2, ("%s:%d: fail", __func__, __LINE__));
3636 
3637 	tmp = (te.te_pad << 16) | (te.te_pga << 8) | te.te_gm;
3638 	if (mac->mac_phy.rev >= 3) {
3639 		tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
3640 		    (0x10 << 24) : (0x70 << 24));
3641 	} else {
3642 		tmp |= ((IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) ?
3643 		    (0x14 << 24) : (0x7f << 24));
3644 	}
3645 	bwn_tab_write(mac, BWN_TAB_4(7, 0xc0 + offset), tmp);
3646 	bwn_tab_write(mac, BWN_TAB_4(7, 0x140 + offset),
3647 	    te.te_bbmult << 20 | te.te_dac << 28);
3648 }
3649 
3650 static void
3651 bwn_phy_lp_gaintbl_write_r01(struct bwn_mac *mac, int offset,
3652     struct bwn_txgain_entry te)
3653 {
3654 
3655 	KASSERT(mac->mac_phy.rev < 2, ("%s:%d: fail", __func__, __LINE__));
3656 
3657 	bwn_tab_write(mac, BWN_TAB_4(10, 0xc0 + offset),
3658 	    (te.te_pad << 11) | (te.te_pga << 7) | (te.te_gm  << 4) |
3659 	    te.te_dac);
3660 	bwn_tab_write(mac, BWN_TAB_4(10, 0x140 + offset), te.te_bbmult << 20);
3661 }
3662