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