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