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