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