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