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