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