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