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