diff options
author | Stefano Brivio <stefano.brivio@polimi.it> | 2007-11-06 16:49:05 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:04:31 -0500 |
commit | 61bca6eb85c863603d6054530e2f65c3b9aba85b (patch) | |
tree | 9b67e165af38ae504d64d3b03882fb4ce3efb016 /drivers/net/wireless/b43/wa.c | |
parent | db9683fb19a0f0da1cb4c296ffe1a8db03333cbc (diff) |
b43: rewrite A PHY initialization
Rewrite and sync A PHY initialization with specs, thus allowing for further
work to be done on 802.11a support. Note that A PHY initialization involves
G PHYs as well.
Signed-off-by: Stefano Brivio <stefano.brivio@polimi.it>
Acked-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/wa.c')
-rw-r--r-- | drivers/net/wireless/b43/wa.c | 668 |
1 files changed, 668 insertions, 0 deletions
diff --git a/drivers/net/wireless/b43/wa.c b/drivers/net/wireless/b43/wa.c new file mode 100644 index 000000000000..2ccbdc09f49d --- /dev/null +++ b/drivers/net/wireless/b43/wa.c | |||
@@ -0,0 +1,668 @@ | |||
1 | /* | ||
2 | |||
3 | Broadcom B43 wireless driver | ||
4 | |||
5 | PHY workarounds. | ||
6 | |||
7 | Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>, | ||
8 | Copyright (c) 2005-2007 Stefano Brivio <st3@riseup.net> | ||
9 | Copyright (c) 2005-2007 Michael Buesch <mbuesch@freenet.de> | ||
10 | Copyright (c) 2005, 2006 Danny van Dyk <kugelfang@gentoo.org> | ||
11 | Copyright (c) 2005, 2006 Andreas Jaggi <andreas.jaggi@waterwave.ch> | ||
12 | |||
13 | This program is free software; you can redistribute it and/or modify | ||
14 | it under the terms of the GNU General Public License as published by | ||
15 | the Free Software Foundation; either version 2 of the License, or | ||
16 | (at your option) any later version. | ||
17 | |||
18 | This program is distributed in the hope that it will be useful, | ||
19 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | GNU General Public License for more details. | ||
22 | |||
23 | You should have received a copy of the GNU General Public License | ||
24 | along with this program; see the file COPYING. If not, write to | ||
25 | the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor, | ||
26 | Boston, MA 02110-1301, USA. | ||
27 | |||
28 | */ | ||
29 | |||
30 | #include "b43.h" | ||
31 | #include "main.h" | ||
32 | #include "tables.h" | ||
33 | #include "phy.h" | ||
34 | #include "wa.h" | ||
35 | |||
36 | static void b43_wa_papd(struct b43_wldev *dev) | ||
37 | { | ||
38 | u16 backup; | ||
39 | |||
40 | backup = b43_ofdmtab_read16(dev, B43_OFDMTAB_PWRDYN2, 0); | ||
41 | b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, 7); | ||
42 | b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 0, 0); | ||
43 | b43_dummy_transmission(dev); | ||
44 | b43_ofdmtab_write16(dev, B43_OFDMTAB_PWRDYN2, 0, backup); | ||
45 | } | ||
46 | |||
47 | static void b43_wa_auxclipthr(struct b43_wldev *dev) | ||
48 | { | ||
49 | b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x3800); | ||
50 | } | ||
51 | |||
52 | static void b43_wa_afcdac(struct b43_wldev *dev) | ||
53 | { | ||
54 | b43_phy_write(dev, 0x0035, 0x03FF); | ||
55 | b43_phy_write(dev, 0x0036, 0x0400); | ||
56 | } | ||
57 | |||
58 | static void b43_wa_txdc_offset(struct b43_wldev *dev) | ||
59 | { | ||
60 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 0, 0x0051); | ||
61 | } | ||
62 | |||
63 | void b43_wa_initgains(struct b43_wldev *dev) | ||
64 | { | ||
65 | struct b43_phy *phy = &dev->phy; | ||
66 | |||
67 | b43_phy_write(dev, B43_PHY_LNAHPFCTL, 0x1FF9); | ||
68 | b43_phy_write(dev, B43_PHY_LPFGAINCTL, | ||
69 | b43_phy_read(dev, B43_PHY_LPFGAINCTL) & 0xFF0F); | ||
70 | if (phy->rev <= 2) | ||
71 | b43_ofdmtab_write16(dev, B43_OFDMTAB_LPFGAIN, 0, 0x1FBF); | ||
72 | b43_radio_write16(dev, 0x0002, 0x1FBF); | ||
73 | |||
74 | b43_phy_write(dev, 0x0024, 0x4680); | ||
75 | b43_phy_write(dev, 0x0020, 0x0003); | ||
76 | b43_phy_write(dev, 0x001D, 0x0F40); | ||
77 | b43_phy_write(dev, 0x001F, 0x1C00); | ||
78 | if (phy->rev <= 3) | ||
79 | b43_phy_write(dev, 0x002A, | ||
80 | (b43_phy_read(dev, 0x002A) & 0x00FF) | 0x0400); | ||
81 | else if (phy->rev == 5) { | ||
82 | b43_phy_write(dev, 0x002A, | ||
83 | (b43_phy_read(dev, 0x002A) & 0x00FF) | 0x1A00); | ||
84 | b43_phy_write(dev, 0x00CC, 0x2121); | ||
85 | } | ||
86 | if (phy->rev >= 3) | ||
87 | b43_phy_write(dev, 0x00BA, 0x3ED5); | ||
88 | } | ||
89 | |||
90 | static void b43_wa_divider(struct b43_wldev *dev) | ||
91 | { | ||
92 | b43_phy_write(dev, 0x002B, b43_phy_read(dev, 0x002B) & ~0x0100); | ||
93 | b43_phy_write(dev, 0x008E, 0x58C1); | ||
94 | } | ||
95 | |||
96 | static void b43_wa_gt(struct b43_wldev *dev) /* Gain table. */ | ||
97 | { | ||
98 | if (dev->phy.rev <= 2) { | ||
99 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 0, 15); | ||
100 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 1, 31); | ||
101 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 2, 42); | ||
102 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 3, 48); | ||
103 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN2, 4, 58); | ||
104 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 0, 19); | ||
105 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 1, 19); | ||
106 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 2, 19); | ||
107 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 3, 19); | ||
108 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 4, 21); | ||
109 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 5, 21); | ||
110 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 6, 25); | ||
111 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 0, 3); | ||
112 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 1, 3); | ||
113 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN1, 2, 7); | ||
114 | } else { | ||
115 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 0, 19); | ||
116 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 1, 19); | ||
117 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 2, 19); | ||
118 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 3, 19); | ||
119 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 4, 21); | ||
120 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 5, 21); | ||
121 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAIN0, 6, 25); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | static void b43_wa_rssi_lt(struct b43_wldev *dev) /* RSSI lookup table */ | ||
126 | { | ||
127 | int i; | ||
128 | |||
129 | for (i = 0; i < 8; i++) | ||
130 | b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i + 8); | ||
131 | for (i = 8; i < 16; i++) | ||
132 | b43_ofdmtab_write16(dev, B43_OFDMTAB_RSSI, i, i - 8); | ||
133 | } | ||
134 | |||
135 | static void b43_wa_analog(struct b43_wldev *dev) | ||
136 | { | ||
137 | struct b43_phy *phy = &dev->phy; | ||
138 | |||
139 | if (phy->analog > 2) { | ||
140 | if (phy->type == B43_PHYTYPE_A) | ||
141 | b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1808); | ||
142 | else | ||
143 | b43_phy_write(dev, B43_PHY_PWRDOWN, 0x1000); | ||
144 | } else { | ||
145 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 3, 0x1044); | ||
146 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 4, 0x7201); | ||
147 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 6, 0x0040); | ||
148 | } | ||
149 | } | ||
150 | |||
151 | static void b43_wa_dac(struct b43_wldev *dev) | ||
152 | { | ||
153 | if (dev->phy.analog == 1) | ||
154 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, | ||
155 | (b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 1) & ~0x0034) | 0x0008); | ||
156 | else | ||
157 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, | ||
158 | (b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 1) & ~0x0078) | 0x0010); | ||
159 | } | ||
160 | |||
161 | static void b43_wa_fft(struct b43_wldev *dev) /* Fine frequency table */ | ||
162 | { | ||
163 | int i; | ||
164 | |||
165 | if (dev->phy.type == B43_PHYTYPE_A) | ||
166 | for (i = 0; i < B43_TAB_FINEFREQA_SIZE; i++) | ||
167 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i, b43_tab_finefreqa[i]); | ||
168 | else | ||
169 | for (i = 0; i < B43_TAB_FINEFREQG_SIZE; i++) | ||
170 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DACRFPABB, i, b43_tab_finefreqg[i]); | ||
171 | } | ||
172 | |||
173 | static void b43_wa_nft(struct b43_wldev *dev) /* Noise figure table */ | ||
174 | { | ||
175 | struct b43_phy *phy = &dev->phy; | ||
176 | int i; | ||
177 | |||
178 | if (phy->type == B43_PHYTYPE_A) { | ||
179 | if (phy->rev == 2) | ||
180 | for (i = 0; i < B43_TAB_NOISEA2_SIZE; i++) | ||
181 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noisea2[i]); | ||
182 | else | ||
183 | for (i = 0; i < B43_TAB_NOISEA3_SIZE; i++) | ||
184 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noisea3[i]); | ||
185 | } else { | ||
186 | if (phy->rev == 1) | ||
187 | for (i = 0; i < B43_TAB_NOISEG1_SIZE; i++) | ||
188 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noiseg1[i]); | ||
189 | else | ||
190 | for (i = 0; i < B43_TAB_NOISEG2_SIZE; i++) | ||
191 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, i, b43_tab_noiseg2[i]); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | static void b43_wa_rt(struct b43_wldev *dev) /* Rotor table */ | ||
196 | { | ||
197 | int i; | ||
198 | |||
199 | for (i = 0; i < B43_TAB_ROTOR_SIZE; i++) | ||
200 | b43_ofdmtab_write32(dev, B43_OFDMTAB_ROTOR, i, b43_tab_rotor[i]); | ||
201 | } | ||
202 | |||
203 | static void b43_wa_nst(struct b43_wldev *dev) /* Noise scale table */ | ||
204 | { | ||
205 | struct b43_phy *phy = &dev->phy; | ||
206 | int i; | ||
207 | |||
208 | if (phy->type == B43_PHYTYPE_A) { | ||
209 | if (phy->rev <= 1) | ||
210 | for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) | ||
211 | b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, | ||
212 | i, 0); | ||
213 | else if (phy->rev == 2) | ||
214 | for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) | ||
215 | b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, | ||
216 | i, b43_tab_noisescalea2[i]); | ||
217 | else if (phy->rev == 3) | ||
218 | for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) | ||
219 | b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, | ||
220 | i, b43_tab_noisescalea3[i]); | ||
221 | else | ||
222 | for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) | ||
223 | b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, | ||
224 | i, b43_tab_noisescaleg3[i]); | ||
225 | } else { | ||
226 | if (phy->rev >= 6) { | ||
227 | if (b43_phy_read(dev, B43_PHY_ENCORE) & B43_PHY_ENCORE_EN) | ||
228 | for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) | ||
229 | b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, | ||
230 | i, b43_tab_noisescaleg3[i]); | ||
231 | else | ||
232 | for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) | ||
233 | b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, | ||
234 | i, b43_tab_noisescaleg2[i]); | ||
235 | } else { | ||
236 | for (i = 0; i < B43_TAB_NOISESCALE_SIZE; i++) | ||
237 | b43_ofdmtab_write16(dev, B43_OFDMTAB_NOISESCALE, | ||
238 | i, b43_tab_noisescaleg1[i]); | ||
239 | } | ||
240 | } | ||
241 | } | ||
242 | |||
243 | static void b43_wa_art(struct b43_wldev *dev) /* ADV retard table */ | ||
244 | { | ||
245 | int i; | ||
246 | |||
247 | for (i = 0; i < B43_TAB_RETARD_SIZE; i++) | ||
248 | b43_ofdmtab_write32(dev, B43_OFDMTAB_ADVRETARD, | ||
249 | i, b43_tab_retard[i]); | ||
250 | } | ||
251 | |||
252 | static void b43_wa_txlna_gain(struct b43_wldev *dev) | ||
253 | { | ||
254 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 13, 0x0000); | ||
255 | } | ||
256 | |||
257 | static void b43_wa_crs_reset(struct b43_wldev *dev) | ||
258 | { | ||
259 | b43_phy_write(dev, 0x002C, 0x0064); | ||
260 | } | ||
261 | |||
262 | static void b43_wa_2060txlna_gain(struct b43_wldev *dev) | ||
263 | { | ||
264 | b43_hf_write(dev, b43_hf_read(dev) | | ||
265 | B43_HF_2060W); | ||
266 | } | ||
267 | |||
268 | static void b43_wa_lms(struct b43_wldev *dev) | ||
269 | { | ||
270 | b43_phy_write(dev, 0x0055, | ||
271 | (b43_phy_read(dev, 0x0055) & 0xFFC0) | 0x0004); | ||
272 | } | ||
273 | |||
274 | static void b43_wa_mixedsignal(struct b43_wldev *dev) | ||
275 | { | ||
276 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 1, 3); | ||
277 | } | ||
278 | |||
279 | static void b43_wa_msst(struct b43_wldev *dev) /* Min sigma square table */ | ||
280 | { | ||
281 | struct b43_phy *phy = &dev->phy; | ||
282 | int i; | ||
283 | const u16 *tab; | ||
284 | |||
285 | if (phy->type == B43_PHYTYPE_A) { | ||
286 | tab = b43_tab_sigmasqr1; | ||
287 | } else if (phy->type == B43_PHYTYPE_G) { | ||
288 | tab = b43_tab_sigmasqr2; | ||
289 | } else { | ||
290 | B43_WARN_ON(1); | ||
291 | return; | ||
292 | } | ||
293 | |||
294 | for (i = 0; i < B43_TAB_SIGMASQR_SIZE; i++) { | ||
295 | b43_ofdmtab_write16(dev, B43_OFDMTAB_MINSIGSQ, | ||
296 | i, tab[i]); | ||
297 | } | ||
298 | } | ||
299 | |||
300 | static void b43_wa_iqadc(struct b43_wldev *dev) | ||
301 | { | ||
302 | if (dev->phy.analog == 4) | ||
303 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DAC, 0, | ||
304 | b43_ofdmtab_read16(dev, B43_OFDMTAB_DAC, 0) & ~0xF000); | ||
305 | } | ||
306 | |||
307 | static void b43_wa_crs_ed(struct b43_wldev *dev) | ||
308 | { | ||
309 | struct b43_phy *phy = &dev->phy; | ||
310 | |||
311 | if (phy->rev == 1) { | ||
312 | b43_phy_write(dev, B43_PHY_CRSTHRES1, 0x4F19); | ||
313 | } else if (phy->rev == 2) { | ||
314 | b43_phy_write(dev, B43_PHY_CRSTHRES1_R1, 0x1861); | ||
315 | b43_phy_write(dev, B43_PHY_CRSTHRES2_R1, 0x1861); | ||
316 | b43_phy_write(dev, B43_PHY_ANTDWELL, | ||
317 | b43_phy_read(dev, B43_PHY_ANTDWELL) | ||
318 | | 0x0800); | ||
319 | } else { | ||
320 | b43_phy_write(dev, B43_PHY_CRSTHRES1_R1, 0x0098); | ||
321 | b43_phy_write(dev, B43_PHY_CRSTHRES2_R1, 0x0070); | ||
322 | b43_phy_write(dev, B43_PHY_OFDM(0xC9), 0x0080); | ||
323 | b43_phy_write(dev, B43_PHY_ANTDWELL, | ||
324 | b43_phy_read(dev, B43_PHY_ANTDWELL) | ||
325 | | 0x0800); | ||
326 | } | ||
327 | } | ||
328 | |||
329 | static void b43_wa_crs_thr(struct b43_wldev *dev) | ||
330 | { | ||
331 | b43_phy_write(dev, B43_PHY_CRS0, | ||
332 | (b43_phy_read(dev, B43_PHY_CRS0) & ~0x03C0) | 0xD000); | ||
333 | } | ||
334 | |||
335 | static void b43_wa_crs_blank(struct b43_wldev *dev) | ||
336 | { | ||
337 | b43_phy_write(dev, B43_PHY_OFDM(0x2C), 0x005A); | ||
338 | } | ||
339 | |||
340 | static void b43_wa_cck_shiftbits(struct b43_wldev *dev) | ||
341 | { | ||
342 | b43_phy_write(dev, B43_PHY_CCKSHIFTBITS, 0x0026); | ||
343 | } | ||
344 | |||
345 | static void b43_wa_wrssi_offset(struct b43_wldev *dev) | ||
346 | { | ||
347 | int i; | ||
348 | |||
349 | if (dev->phy.rev == 1) { | ||
350 | for (i = 0; i < 16; i++) { | ||
351 | b43_ofdmtab_write16(dev, B43_OFDMTAB_WRSSI_R1, | ||
352 | i, 0x0020); | ||
353 | } | ||
354 | } else { | ||
355 | for (i = 0; i < 32; i++) { | ||
356 | b43_ofdmtab_write16(dev, B43_OFDMTAB_WRSSI, | ||
357 | i, 0x0820); | ||
358 | } | ||
359 | } | ||
360 | } | ||
361 | |||
362 | static void b43_wa_txpuoff_rxpuon(struct b43_wldev *dev) | ||
363 | { | ||
364 | b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_0F, 2, 15); | ||
365 | b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_0F, 3, 20); | ||
366 | } | ||
367 | |||
368 | static void b43_wa_altagc(struct b43_wldev *dev) | ||
369 | { | ||
370 | struct b43_phy *phy = &dev->phy; | ||
371 | |||
372 | if (phy->rev == 1) { | ||
373 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 0, 254); | ||
374 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 1, 13); | ||
375 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 2, 19); | ||
376 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1_R1, 3, 25); | ||
377 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 0, 0x2710); | ||
378 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 1, 0x9B83); | ||
379 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 2, 0x9B83); | ||
380 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC2, 3, 0x0F8D); | ||
381 | b43_phy_write(dev, B43_PHY_LMS, 4); | ||
382 | } else { | ||
383 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 0, 254); | ||
384 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 1, 13); | ||
385 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 2, 19); | ||
386 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC1, 3, 25); | ||
387 | } | ||
388 | |||
389 | b43_phy_write(dev, B43_PHY_CCKSHIFTBITS_WA, | ||
390 | (b43_phy_read(dev, B43_PHY_CCKSHIFTBITS_WA) & ~0xFF00) | 0x5700); | ||
391 | b43_phy_write(dev, B43_PHY_OFDM(0x1A), | ||
392 | (b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x007F) | 0x000F); | ||
393 | b43_phy_write(dev, B43_PHY_OFDM(0x1A), | ||
394 | (b43_phy_read(dev, B43_PHY_OFDM(0x1A)) & ~0x3F80) | 0x2B80); | ||
395 | b43_phy_write(dev, B43_PHY_ANTWRSETT, | ||
396 | (b43_phy_read(dev, B43_PHY_ANTWRSETT) & 0xF0FF) | 0x0300); | ||
397 | b43_radio_write16(dev, 0x7A, | ||
398 | b43_radio_read16(dev, 0x7A) | 0x0008); | ||
399 | b43_phy_write(dev, B43_PHY_N1P1GAIN, | ||
400 | (b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x000F) | 0x0008); | ||
401 | b43_phy_write(dev, B43_PHY_P1P2GAIN, | ||
402 | (b43_phy_read(dev, B43_PHY_P1P2GAIN) & ~0x0F00) | 0x0600); | ||
403 | b43_phy_write(dev, B43_PHY_N1N2GAIN, | ||
404 | (b43_phy_read(dev, B43_PHY_N1N2GAIN) & ~0x0F00) | 0x0700); | ||
405 | b43_phy_write(dev, B43_PHY_N1P1GAIN, | ||
406 | (b43_phy_read(dev, B43_PHY_N1P1GAIN) & ~0x0F00) | 0x0100); | ||
407 | if (phy->rev == 1) { | ||
408 | b43_phy_write(dev, B43_PHY_N1N2GAIN, | ||
409 | (b43_phy_read(dev, B43_PHY_N1N2GAIN) | ||
410 | & ~0x000F) | 0x0007); | ||
411 | } | ||
412 | b43_phy_write(dev, B43_PHY_OFDM(0x88), | ||
413 | (b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x00FF) | 0x001C); | ||
414 | b43_phy_write(dev, B43_PHY_OFDM(0x88), | ||
415 | (b43_phy_read(dev, B43_PHY_OFDM(0x88)) & ~0x3F00) | 0x0200); | ||
416 | b43_phy_write(dev, B43_PHY_OFDM(0x96), | ||
417 | (b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0x00FF) | 0x001C); | ||
418 | b43_phy_write(dev, B43_PHY_OFDM(0x89), | ||
419 | (b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x00FF) | 0x0020); | ||
420 | b43_phy_write(dev, B43_PHY_OFDM(0x89), | ||
421 | (b43_phy_read(dev, B43_PHY_OFDM(0x89)) & ~0x3F00) | 0x0200); | ||
422 | b43_phy_write(dev, B43_PHY_OFDM(0x82), | ||
423 | (b43_phy_read(dev, B43_PHY_OFDM(0x82)) & ~0x00FF) | 0x002E); | ||
424 | b43_phy_write(dev, B43_PHY_OFDM(0x96), | ||
425 | (b43_phy_read(dev, B43_PHY_OFDM(0x96)) & ~0xFF00) | 0x1A00); | ||
426 | b43_phy_write(dev, B43_PHY_OFDM(0x81), | ||
427 | (b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0x00FF) | 0x0028); | ||
428 | b43_phy_write(dev, B43_PHY_OFDM(0x81), | ||
429 | (b43_phy_read(dev, B43_PHY_OFDM(0x81)) & ~0xFF00) | 0x2C00); | ||
430 | if (phy->rev == 1) { | ||
431 | b43_phy_write(dev, B43_PHY_PEAK_COUNT, 0x092B); | ||
432 | b43_phy_write(dev, B43_PHY_OFDM(0x1B), | ||
433 | (b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E) | 0x0002); | ||
434 | } else { | ||
435 | b43_phy_write(dev, B43_PHY_OFDM(0x1B), | ||
436 | b43_phy_read(dev, B43_PHY_OFDM(0x1B)) & ~0x001E); | ||
437 | b43_phy_write(dev, B43_PHY_OFDM(0x1F), 0x287A); | ||
438 | b43_phy_write(dev, B43_PHY_LPFGAINCTL, | ||
439 | (b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0x000F) | 0x0004); | ||
440 | if (phy->rev >= 6) { | ||
441 | b43_phy_write(dev, B43_PHY_OFDM(0x22), 0x287A); | ||
442 | b43_phy_write(dev, B43_PHY_LPFGAINCTL, | ||
443 | (b43_phy_read(dev, B43_PHY_LPFGAINCTL) & ~0xF000) | 0x3000); | ||
444 | } | ||
445 | } | ||
446 | b43_phy_write(dev, B43_PHY_DIVSRCHIDX, | ||
447 | (b43_phy_read(dev, B43_PHY_DIVSRCHIDX) & 0x7F7F) | 0x7874); | ||
448 | b43_phy_write(dev, B43_PHY_OFDM(0x8E), 0x1C00); | ||
449 | if (phy->rev == 1) { | ||
450 | b43_phy_write(dev, B43_PHY_DIVP1P2GAIN, | ||
451 | (b43_phy_read(dev, B43_PHY_DIVP1P2GAIN) & ~0x0F00) | 0x0600); | ||
452 | b43_phy_write(dev, B43_PHY_OFDM(0x8B), 0x005E); | ||
453 | b43_phy_write(dev, B43_PHY_ANTWRSETT, | ||
454 | (b43_phy_read(dev, B43_PHY_ANTWRSETT) & ~0x00FF) | 0x001E); | ||
455 | b43_phy_write(dev, B43_PHY_OFDM(0x8D), 0x0002); | ||
456 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 0, 0); | ||
457 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 1, 7); | ||
458 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 2, 16); | ||
459 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3_R1, 3, 28); | ||
460 | } else { | ||
461 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 0, 0); | ||
462 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 1, 7); | ||
463 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 2, 16); | ||
464 | b43_ofdmtab_write16(dev, B43_OFDMTAB_AGC3, 3, 28); | ||
465 | } | ||
466 | if (phy->rev >= 6) { | ||
467 | b43_phy_write(dev, B43_PHY_OFDM(0x26), | ||
468 | b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x0003); | ||
469 | b43_phy_write(dev, B43_PHY_OFDM(0x26), | ||
470 | b43_phy_read(dev, B43_PHY_OFDM(0x26)) & ~0x1000); | ||
471 | } | ||
472 | } | ||
473 | |||
474 | static void b43_wa_tr_ltov(struct b43_wldev *dev) /* TR Lookup Table Original Values */ | ||
475 | { | ||
476 | b43_gtab_write(dev, B43_GTAB_ORIGTR, 0, 0xC480); | ||
477 | } | ||
478 | |||
479 | static void b43_wa_cpll_nonpilot(struct b43_wldev *dev) | ||
480 | { | ||
481 | b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 0, 0); | ||
482 | b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_11, 1, 0); | ||
483 | } | ||
484 | |||
485 | static void b43_wa_rssi_adc(struct b43_wldev *dev) | ||
486 | { | ||
487 | if (dev->phy.analog == 4) | ||
488 | b43_phy_write(dev, 0x00DC, 0x7454); | ||
489 | } | ||
490 | |||
491 | static void b43_wa_boards_a(struct b43_wldev *dev) | ||
492 | { | ||
493 | struct ssb_bus *bus = dev->dev->bus; | ||
494 | |||
495 | if (bus->boardinfo.vendor == SSB_BOARDVENDOR_BCM && | ||
496 | bus->boardinfo.type == SSB_BOARD_BU4306 && | ||
497 | bus->boardinfo.rev < 0x30) { | ||
498 | b43_phy_write(dev, 0x0010, 0xE000); | ||
499 | b43_phy_write(dev, 0x0013, 0x0140); | ||
500 | b43_phy_write(dev, 0x0014, 0x0280); | ||
501 | } else { | ||
502 | if (bus->boardinfo.type == SSB_BOARD_MP4318 && | ||
503 | bus->boardinfo.rev < 0x20) { | ||
504 | b43_phy_write(dev, 0x0013, 0x0210); | ||
505 | b43_phy_write(dev, 0x0014, 0x0840); | ||
506 | } else { | ||
507 | b43_phy_write(dev, 0x0013, 0x0140); | ||
508 | b43_phy_write(dev, 0x0014, 0x0280); | ||
509 | } | ||
510 | if (dev->phy.rev <= 4) | ||
511 | b43_phy_write(dev, 0x0010, 0xE000); | ||
512 | else | ||
513 | b43_phy_write(dev, 0x0010, 0x2000); | ||
514 | b43_ofdmtab_write16(dev, B43_OFDMTAB_DC, 1, 0x0039); | ||
515 | b43_ofdmtab_write16(dev, B43_OFDMTAB_UNKNOWN_APHY, 7, 0x0040); | ||
516 | } | ||
517 | } | ||
518 | |||
519 | static void b43_wa_boards_g(struct b43_wldev *dev) | ||
520 | { | ||
521 | struct ssb_bus *bus = dev->dev->bus; | ||
522 | struct b43_phy *phy = &dev->phy; | ||
523 | |||
524 | if (bus->boardinfo.vendor != SSB_BOARDVENDOR_BCM || | ||
525 | bus->boardinfo.type != SSB_BOARD_BU4306 || | ||
526 | bus->boardinfo.rev != 0x17) { | ||
527 | if (phy->rev < 2) { | ||
528 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 1, 0x0002); | ||
529 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX_R1, 2, 0x0001); | ||
530 | } else { | ||
531 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 1, 0x0002); | ||
532 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 2, 0x0001); | ||
533 | if ((bus->sprom.r1.boardflags_lo & B43_BFL_EXTLNA) && | ||
534 | (phy->rev >= 7)) { | ||
535 | b43_phy_write(dev, B43_PHY_EXTG(0x11), | ||
536 | b43_phy_read(dev, B43_PHY_EXTG(0x11)) & 0xF7FF); | ||
537 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0020, 0x0001); | ||
538 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0021, 0x0001); | ||
539 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0022, 0x0001); | ||
540 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0023, 0x0000); | ||
541 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0000, 0x0000); | ||
542 | b43_ofdmtab_write16(dev, B43_OFDMTAB_GAINX, 0x0003, 0x0002); | ||
543 | } | ||
544 | } | ||
545 | } | ||
546 | if (bus->sprom.r1.boardflags_lo & B43_BFL_FEM) { | ||
547 | b43_phy_write(dev, B43_PHY_GTABCTL, 0x3120); | ||
548 | b43_phy_write(dev, B43_PHY_GTABDATA, 0xC480); | ||
549 | } | ||
550 | } | ||
551 | |||
552 | void b43_wa_all(struct b43_wldev *dev) | ||
553 | { | ||
554 | struct b43_phy *phy = &dev->phy; | ||
555 | |||
556 | if (phy->type == B43_PHYTYPE_A) { | ||
557 | switch (phy->rev) { | ||
558 | case 2: | ||
559 | b43_wa_papd(dev); | ||
560 | b43_wa_auxclipthr(dev); | ||
561 | b43_wa_afcdac(dev); | ||
562 | b43_wa_txdc_offset(dev); | ||
563 | b43_wa_initgains(dev); | ||
564 | b43_wa_divider(dev); | ||
565 | b43_wa_gt(dev); | ||
566 | b43_wa_rssi_lt(dev); | ||
567 | b43_wa_analog(dev); | ||
568 | b43_wa_dac(dev); | ||
569 | b43_wa_fft(dev); | ||
570 | b43_wa_nft(dev); | ||
571 | b43_wa_rt(dev); | ||
572 | b43_wa_nst(dev); | ||
573 | b43_wa_art(dev); | ||
574 | b43_wa_txlna_gain(dev); | ||
575 | b43_wa_crs_reset(dev); | ||
576 | b43_wa_2060txlna_gain(dev); | ||
577 | b43_wa_lms(dev); | ||
578 | break; | ||
579 | case 3: | ||
580 | b43_wa_papd(dev); | ||
581 | b43_wa_mixedsignal(dev); | ||
582 | b43_wa_rssi_lt(dev); | ||
583 | b43_wa_txdc_offset(dev); | ||
584 | b43_wa_initgains(dev); | ||
585 | b43_wa_dac(dev); | ||
586 | b43_wa_nft(dev); | ||
587 | b43_wa_nst(dev); | ||
588 | b43_wa_msst(dev); | ||
589 | b43_wa_analog(dev); | ||
590 | b43_wa_gt(dev); | ||
591 | b43_wa_txpuoff_rxpuon(dev); | ||
592 | b43_wa_txlna_gain(dev); | ||
593 | break; | ||
594 | case 5: | ||
595 | b43_wa_iqadc(dev); | ||
596 | case 6: | ||
597 | b43_wa_papd(dev); | ||
598 | b43_wa_rssi_lt(dev); | ||
599 | b43_wa_txdc_offset(dev); | ||
600 | b43_wa_initgains(dev); | ||
601 | b43_wa_dac(dev); | ||
602 | b43_wa_nft(dev); | ||
603 | b43_wa_nst(dev); | ||
604 | b43_wa_msst(dev); | ||
605 | b43_wa_analog(dev); | ||
606 | b43_wa_gt(dev); | ||
607 | b43_wa_txpuoff_rxpuon(dev); | ||
608 | b43_wa_txlna_gain(dev); | ||
609 | break; | ||
610 | case 7: | ||
611 | b43_wa_iqadc(dev); | ||
612 | b43_wa_papd(dev); | ||
613 | b43_wa_rssi_lt(dev); | ||
614 | b43_wa_txdc_offset(dev); | ||
615 | b43_wa_initgains(dev); | ||
616 | b43_wa_dac(dev); | ||
617 | b43_wa_nft(dev); | ||
618 | b43_wa_nst(dev); | ||
619 | b43_wa_msst(dev); | ||
620 | b43_wa_analog(dev); | ||
621 | b43_wa_gt(dev); | ||
622 | b43_wa_txpuoff_rxpuon(dev); | ||
623 | b43_wa_txlna_gain(dev); | ||
624 | b43_wa_rssi_adc(dev); | ||
625 | default: | ||
626 | B43_WARN_ON(1); | ||
627 | } | ||
628 | b43_wa_boards_a(dev); | ||
629 | } else if (phy->type == B43_PHYTYPE_G) { | ||
630 | switch (phy->rev) { | ||
631 | case 1://XXX review rev1 | ||
632 | b43_wa_crs_ed(dev); | ||
633 | b43_wa_crs_thr(dev); | ||
634 | b43_wa_crs_blank(dev); | ||
635 | b43_wa_cck_shiftbits(dev); | ||
636 | b43_wa_fft(dev); | ||
637 | b43_wa_nft(dev); | ||
638 | b43_wa_rt(dev); | ||
639 | b43_wa_nst(dev); | ||
640 | b43_wa_art(dev); | ||
641 | b43_wa_wrssi_offset(dev); | ||
642 | b43_wa_altagc(dev); | ||
643 | break; | ||
644 | case 2: | ||
645 | case 6: | ||
646 | case 7: | ||
647 | case 8: | ||
648 | b43_wa_tr_ltov(dev); | ||
649 | b43_wa_crs_ed(dev); | ||
650 | b43_wa_rssi_lt(dev); | ||
651 | b43_wa_nft(dev); | ||
652 | b43_wa_nst(dev); | ||
653 | b43_wa_msst(dev); | ||
654 | b43_wa_wrssi_offset(dev); | ||
655 | b43_wa_altagc(dev); | ||
656 | b43_wa_analog(dev); | ||
657 | b43_wa_txpuoff_rxpuon(dev); | ||
658 | break; | ||
659 | default: | ||
660 | B43_WARN_ON(1); | ||
661 | } | ||
662 | b43_wa_boards_g(dev); | ||
663 | } else { /* No N PHY support so far */ | ||
664 | B43_WARN_ON(1); | ||
665 | } | ||
666 | |||
667 | b43_wa_cpll_nonpilot(dev); | ||
668 | } | ||