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