diff options
author | Michael Buesch <mb@bu3sch.de> | 2008-01-17 19:09:25 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:10:44 -0500 |
commit | 95b66bad55b846e02e5b5c8b32ac4a659c28149b (patch) | |
tree | ec1f46c1cf212bc5de6a0450cdcc002481a8e032 /drivers/net/wireless/b43/nphy.c | |
parent | c09c7237eadc65916305835ca1e3ee8a03f01159 (diff) |
b43: Add more N-PHY init code
This also adds lots of TODOs. Oh well. Lots of work. :)
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/nphy.c')
-rw-r--r-- | drivers/net/wireless/b43/nphy.c | 292 |
1 files changed, 291 insertions, 1 deletions
diff --git a/drivers/net/wireless/b43/nphy.c b/drivers/net/wireless/b43/nphy.c index 0b421b120a1a..705131ef4bfa 100644 --- a/drivers/net/wireless/b43/nphy.c +++ b/drivers/net/wireless/b43/nphy.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include "nphy.h" | 29 | #include "nphy.h" |
30 | #include "tables_nphy.h" | 30 | #include "tables_nphy.h" |
31 | 31 | ||
32 | #include <linux/delay.h> | ||
33 | |||
32 | 34 | ||
33 | void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) | 35 | void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) |
34 | {//TODO | 36 | {//TODO |
@@ -191,9 +193,297 @@ void b43_nphy_radio_turn_off(struct b43_wldev *dev) | |||
191 | ~B43_NPHY_RFCTL_CMD_EN); | 193 | ~B43_NPHY_RFCTL_CMD_EN); |
192 | } | 194 | } |
193 | 195 | ||
196 | #define ntab_upload(dev, offset, data) do { \ | ||
197 | unsigned int i; \ | ||
198 | for (i = 0; i < (offset##_SIZE); i++) \ | ||
199 | b43_ntab_write(dev, (offset) + i, (data)[i]); \ | ||
200 | } while (0) | ||
201 | |||
202 | /* Upload the N-PHY tables. */ | ||
203 | static void b43_nphy_tables_init(struct b43_wldev *dev) | ||
204 | { | ||
205 | /* Static tables */ | ||
206 | ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct); | ||
207 | ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup); | ||
208 | ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap); | ||
209 | ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn); | ||
210 | ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel); | ||
211 | ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot); | ||
212 | ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt); | ||
213 | ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0); | ||
214 | ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1); | ||
215 | ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0); | ||
216 | ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1); | ||
217 | ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi); | ||
218 | ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest); | ||
219 | ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs); | ||
220 | |||
221 | /* Volatile tables */ | ||
222 | ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10); | ||
223 | ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11); | ||
224 | ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0); | ||
225 | ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1); | ||
226 | ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0); | ||
227 | ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1); | ||
228 | ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0); | ||
229 | ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1); | ||
230 | ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0); | ||
231 | ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1); | ||
232 | ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0); | ||
233 | ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1); | ||
234 | } | ||
235 | |||
236 | static void b43_nphy_workarounds(struct b43_wldev *dev) | ||
237 | { | ||
238 | struct b43_phy *phy = &dev->phy; | ||
239 | unsigned int i; | ||
240 | |||
241 | b43_phy_set(dev, B43_NPHY_IQFLIP, | ||
242 | B43_NPHY_IQFLIP_ADC1 | B43_NPHY_IQFLIP_ADC2); | ||
243 | //FIXME the following condition is different in the specs. | ||
244 | if (1 /* FIXME band is 2.4GHz */) { | ||
245 | b43_phy_set(dev, B43_NPHY_CLASSCTL, | ||
246 | B43_NPHY_CLASSCTL_CCKEN); | ||
247 | } else { | ||
248 | b43_phy_mask(dev, B43_NPHY_CLASSCTL, | ||
249 | ~B43_NPHY_CLASSCTL_CCKEN); | ||
250 | } | ||
251 | b43_radio_set(dev, B2055_C1_TX_RF_SPARE, 0x8); | ||
252 | b43_phy_write(dev, B43_NPHY_TXFRAMEDELAY, 8); | ||
253 | |||
254 | /* Fixup some tables */ | ||
255 | b43_ntab_write(dev, B43_NTAB16(8, 0x00), 0xA); | ||
256 | b43_ntab_write(dev, B43_NTAB16(8, 0x10), 0xA); | ||
257 | b43_ntab_write(dev, B43_NTAB16(8, 0x02), 0xCDAA); | ||
258 | b43_ntab_write(dev, B43_NTAB16(8, 0x12), 0xCDAA); | ||
259 | b43_ntab_write(dev, B43_NTAB16(8, 0x08), 0); | ||
260 | b43_ntab_write(dev, B43_NTAB16(8, 0x18), 0); | ||
261 | b43_ntab_write(dev, B43_NTAB16(8, 0x07), 0x7AAB); | ||
262 | b43_ntab_write(dev, B43_NTAB16(8, 0x17), 0x7AAB); | ||
263 | b43_ntab_write(dev, B43_NTAB16(8, 0x06), 0x800); | ||
264 | b43_ntab_write(dev, B43_NTAB16(8, 0x16), 0x800); | ||
265 | |||
266 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); | ||
267 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, 0x301); | ||
268 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO2, 0x2D8); | ||
269 | b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, 0x301); | ||
270 | |||
271 | //TODO set RF sequence | ||
272 | |||
273 | /* Set narrowband clip threshold */ | ||
274 | b43_phy_write(dev, B43_NPHY_C1_NBCLIPTHRES, 66); | ||
275 | b43_phy_write(dev, B43_NPHY_C2_NBCLIPTHRES, 66); | ||
276 | |||
277 | /* Set wideband clip 2 threshold */ | ||
278 | b43_phy_maskset(dev, B43_NPHY_C1_CLIPWBTHRES, | ||
279 | ~B43_NPHY_C1_CLIPWBTHRES_CLIP2, | ||
280 | 21 << B43_NPHY_C1_CLIPWBTHRES_CLIP2_SHIFT); | ||
281 | b43_phy_maskset(dev, B43_NPHY_C2_CLIPWBTHRES, | ||
282 | ~B43_NPHY_C2_CLIPWBTHRES_CLIP2, | ||
283 | 21 << B43_NPHY_C2_CLIPWBTHRES_CLIP2_SHIFT); | ||
284 | |||
285 | /* Set Clip 2 detect */ | ||
286 | b43_phy_set(dev, B43_NPHY_C1_CGAINI, | ||
287 | B43_NPHY_C1_CGAINI_CL2DETECT); | ||
288 | b43_phy_set(dev, B43_NPHY_C2_CGAINI, | ||
289 | B43_NPHY_C2_CGAINI_CL2DETECT); | ||
290 | |||
291 | if (0 /*FIXME*/) { | ||
292 | /* Set dwell lengths */ | ||
293 | b43_phy_write(dev, B43_NPHY_CLIP1_NBDWELL_LEN, 43); | ||
294 | b43_phy_write(dev, B43_NPHY_CLIP2_NBDWELL_LEN, 43); | ||
295 | b43_phy_write(dev, B43_NPHY_W1CLIP1_DWELL_LEN, 9); | ||
296 | b43_phy_write(dev, B43_NPHY_W1CLIP2_DWELL_LEN, 9); | ||
297 | |||
298 | /* Set gain backoff */ | ||
299 | b43_phy_maskset(dev, B43_NPHY_C1_CGAINI, | ||
300 | ~B43_NPHY_C1_CGAINI_GAINBKOFF, | ||
301 | 1 << B43_NPHY_C1_CGAINI_GAINBKOFF_SHIFT); | ||
302 | b43_phy_maskset(dev, B43_NPHY_C2_CGAINI, | ||
303 | ~B43_NPHY_C2_CGAINI_GAINBKOFF, | ||
304 | 1 << B43_NPHY_C2_CGAINI_GAINBKOFF_SHIFT); | ||
305 | |||
306 | /* Set HPVGA2 index */ | ||
307 | b43_phy_maskset(dev, B43_NPHY_C1_INITGAIN, | ||
308 | ~B43_NPHY_C1_INITGAIN_HPVGA2, | ||
309 | 6 << B43_NPHY_C1_INITGAIN_HPVGA2_SHIFT); | ||
310 | b43_phy_maskset(dev, B43_NPHY_C2_INITGAIN, | ||
311 | ~B43_NPHY_C2_INITGAIN_HPVGA2, | ||
312 | 6 << B43_NPHY_C2_INITGAIN_HPVGA2_SHIFT); | ||
313 | |||
314 | //FIXME verify that the specs really mean to use autoinc here. | ||
315 | for (i = 0; i < 3; i++) | ||
316 | b43_ntab_write(dev, B43_NTAB16(7, 0x106) + i, 0x673); | ||
317 | } | ||
318 | |||
319 | /* Set minimum gain value */ | ||
320 | b43_phy_maskset(dev, B43_NPHY_C1_MINMAX_GAIN, | ||
321 | ~B43_NPHY_C1_MINGAIN, | ||
322 | 23 << B43_NPHY_C1_MINGAIN_SHIFT); | ||
323 | b43_phy_maskset(dev, B43_NPHY_C2_MINMAX_GAIN, | ||
324 | ~B43_NPHY_C2_MINGAIN, | ||
325 | 23 << B43_NPHY_C2_MINGAIN_SHIFT); | ||
326 | |||
327 | if (phy->rev < 2) { | ||
328 | b43_phy_mask(dev, B43_NPHY_SCRAM_SIGCTL, | ||
329 | ~B43_NPHY_SCRAM_SIGCTL_SCM); | ||
330 | } | ||
331 | |||
332 | /* Set phase track alpha and beta */ | ||
333 | b43_phy_write(dev, B43_NPHY_PHASETR_A0, 0x125); | ||
334 | b43_phy_write(dev, B43_NPHY_PHASETR_A1, 0x1B3); | ||
335 | b43_phy_write(dev, B43_NPHY_PHASETR_A2, 0x105); | ||
336 | b43_phy_write(dev, B43_NPHY_PHASETR_B0, 0x16E); | ||
337 | b43_phy_write(dev, B43_NPHY_PHASETR_B1, 0xCD); | ||
338 | b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); | ||
339 | } | ||
340 | |||
341 | static void b43_nphy_reset_cca(struct b43_wldev *dev) | ||
342 | { | ||
343 | u16 bbcfg; | ||
344 | |||
345 | ssb_write32(dev->dev, SSB_TMSLOW, | ||
346 | ssb_read32(dev->dev, SSB_TMSLOW) | SSB_TMSLOW_FGC); | ||
347 | bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG); | ||
348 | b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTCCA); | ||
349 | b43_phy_write(dev, B43_NPHY_BBCFG, | ||
350 | bbcfg & ~B43_NPHY_BBCFG_RSTCCA); | ||
351 | ssb_write32(dev->dev, SSB_TMSLOW, | ||
352 | ssb_read32(dev->dev, SSB_TMSLOW) & ~SSB_TMSLOW_FGC); | ||
353 | } | ||
354 | |||
355 | enum b43_nphy_rf_sequence { | ||
356 | B43_RFSEQ_RX2TX, | ||
357 | B43_RFSEQ_TX2RX, | ||
358 | B43_RFSEQ_RESET2RX, | ||
359 | B43_RFSEQ_UPDATE_GAINH, | ||
360 | B43_RFSEQ_UPDATE_GAINL, | ||
361 | B43_RFSEQ_UPDATE_GAINU, | ||
362 | }; | ||
363 | |||
364 | static void b43_nphy_force_rf_sequence(struct b43_wldev *dev, | ||
365 | enum b43_nphy_rf_sequence seq) | ||
366 | { | ||
367 | static const u16 trigger[] = { | ||
368 | [B43_RFSEQ_RX2TX] = B43_NPHY_RFSEQTR_RX2TX, | ||
369 | [B43_RFSEQ_TX2RX] = B43_NPHY_RFSEQTR_TX2RX, | ||
370 | [B43_RFSEQ_RESET2RX] = B43_NPHY_RFSEQTR_RST2RX, | ||
371 | [B43_RFSEQ_UPDATE_GAINH] = B43_NPHY_RFSEQTR_UPGH, | ||
372 | [B43_RFSEQ_UPDATE_GAINL] = B43_NPHY_RFSEQTR_UPGL, | ||
373 | [B43_RFSEQ_UPDATE_GAINU] = B43_NPHY_RFSEQTR_UPGU, | ||
374 | }; | ||
375 | int i; | ||
376 | |||
377 | B43_WARN_ON(seq >= ARRAY_SIZE(trigger)); | ||
378 | |||
379 | b43_phy_set(dev, B43_NPHY_RFSEQMODE, | ||
380 | B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER); | ||
381 | b43_phy_set(dev, B43_NPHY_RFSEQTR, trigger[seq]); | ||
382 | for (i = 0; i < 200; i++) { | ||
383 | if (!(b43_phy_read(dev, B43_NPHY_RFSEQST) & trigger[seq])) | ||
384 | goto ok; | ||
385 | msleep(1); | ||
386 | } | ||
387 | b43err(dev->wl, "RF sequence status timeout\n"); | ||
388 | ok: | ||
389 | b43_phy_mask(dev, B43_NPHY_RFSEQMODE, | ||
390 | ~(B43_NPHY_RFSEQMODE_CAOVER | B43_NPHY_RFSEQMODE_TROVER)); | ||
391 | } | ||
392 | |||
393 | static void b43_nphy_bphy_init(struct b43_wldev *dev) | ||
394 | { | ||
395 | unsigned int i; | ||
396 | u16 val; | ||
397 | |||
398 | val = 0x1E1F; | ||
399 | for (i = 0; i < 14; i++) { | ||
400 | b43_phy_write(dev, B43_PHY_N_BMODE(0x88 + i), val); | ||
401 | val -= 0x202; | ||
402 | } | ||
403 | val = 0x3E3F; | ||
404 | for (i = 0; i < 16; i++) { | ||
405 | b43_phy_write(dev, B43_PHY_N_BMODE(0x97 + i), val); | ||
406 | val -= 0x202; | ||
407 | } | ||
408 | b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); | ||
409 | } | ||
410 | |||
411 | /* RSSI Calibration */ | ||
412 | static void b43_nphy_rssi_cal(struct b43_wldev *dev, u8 type) | ||
413 | { | ||
414 | //TODO | ||
415 | } | ||
416 | |||
194 | int b43_phy_initn(struct b43_wldev *dev) | 417 | int b43_phy_initn(struct b43_wldev *dev) |
195 | { | 418 | { |
196 | b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n"); | 419 | struct b43_phy *phy = &dev->phy; |
420 | u16 tmp; | ||
421 | |||
422 | //TODO: Spectral management | ||
423 | b43_nphy_tables_init(dev); | ||
424 | |||
425 | /* Clear all overrides */ | ||
426 | b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0); | ||
427 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, 0); | ||
428 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, 0); | ||
429 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC3, 0); | ||
430 | b43_phy_write(dev, B43_NPHY_RFCTL_INTC4, 0); | ||
431 | b43_phy_mask(dev, B43_NPHY_RFSEQMODE, | ||
432 | ~(B43_NPHY_RFSEQMODE_CAOVER | | ||
433 | B43_NPHY_RFSEQMODE_TROVER)); | ||
434 | b43_phy_write(dev, B43_NPHY_AFECTL_OVER, 0); | ||
435 | |||
436 | tmp = (phy->rev < 2) ? 64 : 59; | ||
437 | b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, | ||
438 | ~B43_NPHY_BPHY_CTL3_SCALE, | ||
439 | tmp << B43_NPHY_BPHY_CTL3_SCALE_SHIFT); | ||
440 | |||
441 | b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20); | ||
442 | b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20); | ||
443 | |||
444 | b43_phy_write(dev, B43_NPHY_TXREALFD, 184); | ||
445 | b43_phy_write(dev, B43_NPHY_MIMO_CRSTXEXT, 200); | ||
446 | b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 80); | ||
447 | b43_phy_write(dev, B43_NPHY_C2_BCLIPBKOFF, 511); | ||
197 | 448 | ||
449 | //TODO MIMO-Config | ||
450 | //TODO Update TX/RX chain | ||
451 | |||
452 | if (phy->rev < 2) { | ||
453 | b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8); | ||
454 | b43_phy_write(dev, B43_NPHY_DUP40_BL, 0x9A4); | ||
455 | } | ||
456 | b43_nphy_workarounds(dev); | ||
457 | b43_nphy_reset_cca(dev); | ||
458 | |||
459 | ssb_write32(dev->dev, SSB_TMSLOW, | ||
460 | ssb_read32(dev->dev, SSB_TMSLOW) | B43_TMSLOW_MACPHYCLKEN); | ||
461 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); | ||
462 | b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); | ||
463 | |||
464 | b43_phy_read(dev, B43_NPHY_CLASSCTL); /* dummy read */ | ||
465 | //TODO read core1/2 clip1 thres regs | ||
466 | |||
467 | if (1 /* FIXME Band is 2.4GHz */) | ||
468 | b43_nphy_bphy_init(dev); | ||
469 | //TODO disable TX power control | ||
470 | //TODO Fix the TX power settings | ||
471 | //TODO Init periodic calibration with reason 3 | ||
472 | b43_nphy_rssi_cal(dev, 2); | ||
473 | b43_nphy_rssi_cal(dev, 0); | ||
474 | b43_nphy_rssi_cal(dev, 1); | ||
475 | //TODO get TX gain | ||
476 | //TODO init superswitch | ||
477 | //TODO calibrate LO | ||
478 | //TODO idle TSSI TX pctl | ||
479 | //TODO TX power control power setup | ||
480 | //TODO table writes | ||
481 | //TODO TX power control coefficients | ||
482 | //TODO enable TX power control | ||
483 | //TODO control antenna selection | ||
484 | //TODO init radar detection | ||
485 | //TODO reset channel if changed | ||
486 | |||
487 | b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n"); | ||
198 | return 0; | 488 | return 0; |
199 | } | 489 | } |