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