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