3 Broadcom B43legacy wireless driver
5 Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
6 Stefano Brivio <st3@riseup.net>
7 Michael Buesch <mbuesch@freenet.de>
8 Danny van Dyk <kugelfang@gentoo.org>
9 Andreas Jaggi <andreas.jaggi@waterwave.ch>
10 Copyright (c) 2007 Larry Finger <Larry.Finger@lwfinger.net>
12 Some parts of the code in this file are derived from the ipw2200
13 driver Copyright(c) 2003 - 2004 Intel Corporation.
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public License
26 along with this program; see the file COPYING. If not, write to
27 the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
28 Boston, MA 02110-1301, USA.
32 #include <linux/delay.h>
34 #include "b43legacy.h"
41 /* Table for b43legacy_radio_calibrationvalue() */
42 static const u16 rcc_table
[16] = {
43 0x0002, 0x0003, 0x0001, 0x000F,
44 0x0006, 0x0007, 0x0005, 0x000F,
45 0x000A, 0x000B, 0x0009, 0x000F,
46 0x000E, 0x000F, 0x000D, 0x000F,
49 /* Reverse the bits of a 4bit value.
50 * Example: 1101 is flipped 1011
52 static u16
flip_4bit(u16 value
)
56 B43legacy_BUG_ON(!((value
& ~0x000F) == 0x0000));
58 flipped
|= (value
& 0x0001) << 3;
59 flipped
|= (value
& 0x0002) << 1;
60 flipped
|= (value
& 0x0004) >> 1;
61 flipped
|= (value
& 0x0008) >> 3;
66 /* Get the freq, as it has to be written to the device. */
68 u16
channel2freq_bg(u8 channel
)
70 /* Frequencies are given as frequencies_bg[index] + 2.4GHz
71 * Starting with channel 1
73 static const u16 frequencies_bg
[14] = {
80 if (unlikely(channel
< 1 || channel
> 14)) {
81 printk(KERN_INFO
"b43legacy: Channel %d is out of range\n",
87 return frequencies_bg
[channel
- 1];
90 void b43legacy_radio_lock(struct b43legacy_wldev
*dev
)
94 status
= b43legacy_read32(dev
, B43legacy_MMIO_STATUS_BITFIELD
);
95 status
|= B43legacy_SBF_RADIOREG_LOCK
;
96 b43legacy_write32(dev
, B43legacy_MMIO_STATUS_BITFIELD
, status
);
101 void b43legacy_radio_unlock(struct b43legacy_wldev
*dev
)
105 b43legacy_read16(dev
, B43legacy_MMIO_PHY_VER
); /* dummy read */
106 status
= b43legacy_read32(dev
, B43legacy_MMIO_STATUS_BITFIELD
);
107 status
&= ~B43legacy_SBF_RADIOREG_LOCK
;
108 b43legacy_write32(dev
, B43legacy_MMIO_STATUS_BITFIELD
, status
);
112 u16
b43legacy_radio_read16(struct b43legacy_wldev
*dev
, u16 offset
)
114 struct b43legacy_phy
*phy
= &dev
->phy
;
117 case B43legacy_PHYTYPE_B
:
118 if (phy
->radio_ver
== 0x2053) {
121 else if (offset
< 0x80)
123 } else if (phy
->radio_ver
== 0x2050)
126 B43legacy_WARN_ON(1);
128 case B43legacy_PHYTYPE_G
:
135 b43legacy_write16(dev
, B43legacy_MMIO_RADIO_CONTROL
, offset
);
136 return b43legacy_read16(dev
, B43legacy_MMIO_RADIO_DATA_LOW
);
139 void b43legacy_radio_write16(struct b43legacy_wldev
*dev
, u16 offset
, u16 val
)
141 b43legacy_write16(dev
, B43legacy_MMIO_RADIO_CONTROL
, offset
);
143 b43legacy_write16(dev
, B43legacy_MMIO_RADIO_DATA_LOW
, val
);
146 static void b43legacy_set_all_gains(struct b43legacy_wldev
*dev
,
147 s16 first
, s16 second
, s16 third
)
149 struct b43legacy_phy
*phy
= &dev
->phy
;
162 for (i
= 0; i
< 4; i
++)
163 b43legacy_ilt_write(dev
, offset
+ i
, first
);
165 for (i
= start
; i
< end
; i
++)
166 b43legacy_ilt_write(dev
, offset
+ i
, second
);
169 tmp
= ((u16
)third
<< 14) | ((u16
)third
<< 6);
170 b43legacy_phy_write(dev
, 0x04A0,
171 (b43legacy_phy_read(dev
, 0x04A0) & 0xBFBF)
173 b43legacy_phy_write(dev
, 0x04A1,
174 (b43legacy_phy_read(dev
, 0x04A1) & 0xBFBF)
176 b43legacy_phy_write(dev
, 0x04A2,
177 (b43legacy_phy_read(dev
, 0x04A2) & 0xBFBF)
180 b43legacy_dummy_transmission(dev
);
183 static void b43legacy_set_original_gains(struct b43legacy_wldev
*dev
)
185 struct b43legacy_phy
*phy
= &dev
->phy
;
198 for (i
= 0; i
< 4; i
++) {
200 tmp
|= (i
& 0x0001) << 1;
201 tmp
|= (i
& 0x0002) >> 1;
203 b43legacy_ilt_write(dev
, offset
+ i
, tmp
);
206 for (i
= start
; i
< end
; i
++)
207 b43legacy_ilt_write(dev
, offset
+ i
, i
- start
);
209 b43legacy_phy_write(dev
, 0x04A0,
210 (b43legacy_phy_read(dev
, 0x04A0) & 0xBFBF)
212 b43legacy_phy_write(dev
, 0x04A1,
213 (b43legacy_phy_read(dev
, 0x04A1) & 0xBFBF)
215 b43legacy_phy_write(dev
, 0x04A2,
216 (b43legacy_phy_read(dev
, 0x04A2) & 0xBFBF)
218 b43legacy_dummy_transmission(dev
);
221 /* Synthetic PU workaround */
222 static void b43legacy_synth_pu_workaround(struct b43legacy_wldev
*dev
,
225 struct b43legacy_phy
*phy
= &dev
->phy
;
229 if (phy
->radio_ver
!= 0x2050 || phy
->radio_rev
>= 6)
230 /* We do not need the workaround. */
234 b43legacy_write16(dev
, B43legacy_MMIO_CHANNEL
,
235 channel2freq_bg(channel
+ 4));
237 b43legacy_write16(dev
, B43legacy_MMIO_CHANNEL
,
238 channel2freq_bg(channel
));
240 b43legacy_write16(dev
, B43legacy_MMIO_CHANNEL
,
241 channel2freq_bg(channel
));
244 u8
b43legacy_radio_aci_detect(struct b43legacy_wldev
*dev
, u8 channel
)
246 struct b43legacy_phy
*phy
= &dev
->phy
;
254 saved
= b43legacy_phy_read(dev
, 0x0403);
255 b43legacy_radio_selectchannel(dev
, channel
, 0);
256 b43legacy_phy_write(dev
, 0x0403, (saved
& 0xFFF8) | 5);
257 if (phy
->aci_hw_rssi
)
258 rssi
= b43legacy_phy_read(dev
, 0x048A) & 0x3F;
261 /* clamp temp to signed 5bit */
264 for (i
= 0; i
< 100; i
++) {
265 temp
= (b43legacy_phy_read(dev
, 0x047F) >> 8) & 0x3F;
273 b43legacy_phy_write(dev
, 0x0403, saved
);
278 u8
b43legacy_radio_aci_scan(struct b43legacy_wldev
*dev
)
280 struct b43legacy_phy
*phy
= &dev
->phy
;
282 unsigned int channel
= phy
->channel
;
287 unsigned long phylock_flags
;
289 if (!((phy
->type
== B43legacy_PHYTYPE_G
) && (phy
->rev
> 0)))
292 b43legacy_phy_lock(dev
, phylock_flags
);
293 b43legacy_radio_lock(dev
);
294 b43legacy_phy_write(dev
, 0x0802,
295 b43legacy_phy_read(dev
, 0x0802) & 0xFFFC);
296 b43legacy_phy_write(dev
, B43legacy_PHY_G_CRS
,
297 b43legacy_phy_read(dev
, B43legacy_PHY_G_CRS
)
299 b43legacy_set_all_gains(dev
, 3, 8, 1);
301 start
= (channel
- 5 > 0) ? channel
- 5 : 1;
302 end
= (channel
+ 5 < 14) ? channel
+ 5 : 13;
304 for (i
= start
; i
<= end
; i
++) {
305 if (abs(channel
- i
) > 2)
306 ret
[i
-1] = b43legacy_radio_aci_detect(dev
, i
);
308 b43legacy_radio_selectchannel(dev
, channel
, 0);
309 b43legacy_phy_write(dev
, 0x0802,
310 (b43legacy_phy_read(dev
, 0x0802) & 0xFFFC)
312 b43legacy_phy_write(dev
, 0x0403,
313 b43legacy_phy_read(dev
, 0x0403) & 0xFFF8);
314 b43legacy_phy_write(dev
, B43legacy_PHY_G_CRS
,
315 b43legacy_phy_read(dev
, B43legacy_PHY_G_CRS
)
317 b43legacy_set_original_gains(dev
);
318 for (i
= 0; i
< 13; i
++) {
321 end
= (i
+ 5 < 13) ? i
+ 5 : 13;
322 for (j
= i
; j
< end
; j
++)
325 b43legacy_radio_unlock(dev
);
326 b43legacy_phy_unlock(dev
, phylock_flags
);
328 return ret
[channel
- 1];
331 /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
332 void b43legacy_nrssi_hw_write(struct b43legacy_wldev
*dev
, u16 offset
, s16 val
)
334 b43legacy_phy_write(dev
, B43legacy_PHY_NRSSILT_CTRL
, offset
);
336 b43legacy_phy_write(dev
, B43legacy_PHY_NRSSILT_DATA
, (u16
)val
);
339 /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
340 s16
b43legacy_nrssi_hw_read(struct b43legacy_wldev
*dev
, u16 offset
)
344 b43legacy_phy_write(dev
, B43legacy_PHY_NRSSILT_CTRL
, offset
);
345 val
= b43legacy_phy_read(dev
, B43legacy_PHY_NRSSILT_DATA
);
350 /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
351 void b43legacy_nrssi_hw_update(struct b43legacy_wldev
*dev
, u16 val
)
356 for (i
= 0; i
< 64; i
++) {
357 tmp
= b43legacy_nrssi_hw_read(dev
, i
);
359 tmp
= limit_value(tmp
, -32, 31);
360 b43legacy_nrssi_hw_write(dev
, i
, tmp
);
364 /* http://bcm-specs.sipsolutions.net/NRSSILookupTable */
365 void b43legacy_nrssi_mem_update(struct b43legacy_wldev
*dev
)
367 struct b43legacy_phy
*phy
= &dev
->phy
;
372 delta
= 0x1F - phy
->nrssi
[0];
373 for (i
= 0; i
< 64; i
++) {
374 tmp
= (i
- delta
) * phy
->nrssislope
;
377 tmp
= limit_value(tmp
, 0, 0x3F);
378 phy
->nrssi_lt
[i
] = tmp
;
382 static void b43legacy_calc_nrssi_offset(struct b43legacy_wldev
*dev
)
384 struct b43legacy_phy
*phy
= &dev
->phy
;
385 u16 backup
[20] = { 0 };
390 backup
[0] = b43legacy_phy_read(dev
, 0x0001);
391 backup
[1] = b43legacy_phy_read(dev
, 0x0811);
392 backup
[2] = b43legacy_phy_read(dev
, 0x0812);
393 backup
[3] = b43legacy_phy_read(dev
, 0x0814);
394 backup
[4] = b43legacy_phy_read(dev
, 0x0815);
395 backup
[5] = b43legacy_phy_read(dev
, 0x005A);
396 backup
[6] = b43legacy_phy_read(dev
, 0x0059);
397 backup
[7] = b43legacy_phy_read(dev
, 0x0058);
398 backup
[8] = b43legacy_phy_read(dev
, 0x000A);
399 backup
[9] = b43legacy_phy_read(dev
, 0x0003);
400 backup
[10] = b43legacy_radio_read16(dev
, 0x007A);
401 backup
[11] = b43legacy_radio_read16(dev
, 0x0043);
403 b43legacy_phy_write(dev
, 0x0429,
404 b43legacy_phy_read(dev
, 0x0429) & 0x7FFF);
405 b43legacy_phy_write(dev
, 0x0001,
406 (b43legacy_phy_read(dev
, 0x0001) & 0x3FFF)
408 b43legacy_phy_write(dev
, 0x0811,
409 b43legacy_phy_read(dev
, 0x0811) | 0x000C);
410 b43legacy_phy_write(dev
, 0x0812,
411 (b43legacy_phy_read(dev
, 0x0812) & 0xFFF3)
413 b43legacy_phy_write(dev
, 0x0802,
414 b43legacy_phy_read(dev
, 0x0802) & ~(0x1 | 0x2));
416 backup
[12] = b43legacy_phy_read(dev
, 0x002E);
417 backup
[13] = b43legacy_phy_read(dev
, 0x002F);
418 backup
[14] = b43legacy_phy_read(dev
, 0x080F);
419 backup
[15] = b43legacy_phy_read(dev
, 0x0810);
420 backup
[16] = b43legacy_phy_read(dev
, 0x0801);
421 backup
[17] = b43legacy_phy_read(dev
, 0x0060);
422 backup
[18] = b43legacy_phy_read(dev
, 0x0014);
423 backup
[19] = b43legacy_phy_read(dev
, 0x0478);
425 b43legacy_phy_write(dev
, 0x002E, 0);
426 b43legacy_phy_write(dev
, 0x002F, 0);
427 b43legacy_phy_write(dev
, 0x080F, 0);
428 b43legacy_phy_write(dev
, 0x0810, 0);
429 b43legacy_phy_write(dev
, 0x0478,
430 b43legacy_phy_read(dev
, 0x0478) | 0x0100);
431 b43legacy_phy_write(dev
, 0x0801,
432 b43legacy_phy_read(dev
, 0x0801) | 0x0040);
433 b43legacy_phy_write(dev
, 0x0060,
434 b43legacy_phy_read(dev
, 0x0060) | 0x0040);
435 b43legacy_phy_write(dev
, 0x0014,
436 b43legacy_phy_read(dev
, 0x0014) | 0x0200);
438 b43legacy_radio_write16(dev
, 0x007A,
439 b43legacy_radio_read16(dev
, 0x007A) | 0x0070);
440 b43legacy_radio_write16(dev
, 0x007A,
441 b43legacy_radio_read16(dev
, 0x007A) | 0x0080);
444 v47F
= (s16
)((b43legacy_phy_read(dev
, 0x047F) >> 8) & 0x003F);
448 for (i
= 7; i
>= 4; i
--) {
449 b43legacy_radio_write16(dev
, 0x007B, i
);
451 v47F
= (s16
)((b43legacy_phy_read(dev
, 0x047F) >> 8)
455 if (v47F
< 31 && saved
== 0xFFFF)
461 b43legacy_radio_write16(dev
, 0x007A,
462 b43legacy_radio_read16(dev
, 0x007A)
464 b43legacy_phy_write(dev
, 0x0814,
465 b43legacy_phy_read(dev
, 0x0814) | 0x0001);
466 b43legacy_phy_write(dev
, 0x0815,
467 b43legacy_phy_read(dev
, 0x0815) & 0xFFFE);
468 b43legacy_phy_write(dev
, 0x0811,
469 b43legacy_phy_read(dev
, 0x0811) | 0x000C);
470 b43legacy_phy_write(dev
, 0x0812,
471 b43legacy_phy_read(dev
, 0x0812) | 0x000C);
472 b43legacy_phy_write(dev
, 0x0811,
473 b43legacy_phy_read(dev
, 0x0811) | 0x0030);
474 b43legacy_phy_write(dev
, 0x0812,
475 b43legacy_phy_read(dev
, 0x0812) | 0x0030);
476 b43legacy_phy_write(dev
, 0x005A, 0x0480);
477 b43legacy_phy_write(dev
, 0x0059, 0x0810);
478 b43legacy_phy_write(dev
, 0x0058, 0x000D);
479 if (phy
->analog
== 0)
480 b43legacy_phy_write(dev
, 0x0003, 0x0122);
482 b43legacy_phy_write(dev
, 0x000A,
483 b43legacy_phy_read(dev
, 0x000A)
485 b43legacy_phy_write(dev
, 0x0814,
486 b43legacy_phy_read(dev
, 0x0814) | 0x0004);
487 b43legacy_phy_write(dev
, 0x0815,
488 b43legacy_phy_read(dev
, 0x0815) & 0xFFFB);
489 b43legacy_phy_write(dev
, 0x0003,
490 (b43legacy_phy_read(dev
, 0x0003) & 0xFF9F)
492 b43legacy_radio_write16(dev
, 0x007A,
493 b43legacy_radio_read16(dev
, 0x007A)
495 b43legacy_set_all_gains(dev
, 3, 0, 1);
496 b43legacy_radio_write16(dev
, 0x0043,
497 (b43legacy_radio_read16(dev
, 0x0043)
500 v47F
= (s16
)((b43legacy_phy_read(dev
, 0x047F) >> 8) & 0x003F);
504 for (i
= 0; i
< 4; i
++) {
505 b43legacy_radio_write16(dev
, 0x007B, i
);
507 v47F
= (s16
)((b43legacy_phy_read(dev
, 0x047F) >>
511 if (v47F
> -31 && saved
== 0xFFFF)
519 b43legacy_radio_write16(dev
, 0x007B, saved
);
522 b43legacy_phy_write(dev
, 0x002E, backup
[12]);
523 b43legacy_phy_write(dev
, 0x002F, backup
[13]);
524 b43legacy_phy_write(dev
, 0x080F, backup
[14]);
525 b43legacy_phy_write(dev
, 0x0810, backup
[15]);
527 b43legacy_phy_write(dev
, 0x0814, backup
[3]);
528 b43legacy_phy_write(dev
, 0x0815, backup
[4]);
529 b43legacy_phy_write(dev
, 0x005A, backup
[5]);
530 b43legacy_phy_write(dev
, 0x0059, backup
[6]);
531 b43legacy_phy_write(dev
, 0x0058, backup
[7]);
532 b43legacy_phy_write(dev
, 0x000A, backup
[8]);
533 b43legacy_phy_write(dev
, 0x0003, backup
[9]);
534 b43legacy_radio_write16(dev
, 0x0043, backup
[11]);
535 b43legacy_radio_write16(dev
, 0x007A, backup
[10]);
536 b43legacy_phy_write(dev
, 0x0802,
537 b43legacy_phy_read(dev
, 0x0802) | 0x1 | 0x2);
538 b43legacy_phy_write(dev
, 0x0429,
539 b43legacy_phy_read(dev
, 0x0429) | 0x8000);
540 b43legacy_set_original_gains(dev
);
542 b43legacy_phy_write(dev
, 0x0801, backup
[16]);
543 b43legacy_phy_write(dev
, 0x0060, backup
[17]);
544 b43legacy_phy_write(dev
, 0x0014, backup
[18]);
545 b43legacy_phy_write(dev
, 0x0478, backup
[19]);
547 b43legacy_phy_write(dev
, 0x0001, backup
[0]);
548 b43legacy_phy_write(dev
, 0x0812, backup
[2]);
549 b43legacy_phy_write(dev
, 0x0811, backup
[1]);
552 void b43legacy_calc_nrssi_slope(struct b43legacy_wldev
*dev
)
554 struct b43legacy_phy
*phy
= &dev
->phy
;
555 u16 backup
[18] = { 0 };
561 case B43legacy_PHYTYPE_B
:
562 backup
[0] = b43legacy_radio_read16(dev
, 0x007A);
563 backup
[1] = b43legacy_radio_read16(dev
, 0x0052);
564 backup
[2] = b43legacy_radio_read16(dev
, 0x0043);
565 backup
[3] = b43legacy_phy_read(dev
, 0x0030);
566 backup
[4] = b43legacy_phy_read(dev
, 0x0026);
567 backup
[5] = b43legacy_phy_read(dev
, 0x0015);
568 backup
[6] = b43legacy_phy_read(dev
, 0x002A);
569 backup
[7] = b43legacy_phy_read(dev
, 0x0020);
570 backup
[8] = b43legacy_phy_read(dev
, 0x005A);
571 backup
[9] = b43legacy_phy_read(dev
, 0x0059);
572 backup
[10] = b43legacy_phy_read(dev
, 0x0058);
573 backup
[11] = b43legacy_read16(dev
, 0x03E2);
574 backup
[12] = b43legacy_read16(dev
, 0x03E6);
575 backup
[13] = b43legacy_read16(dev
, B43legacy_MMIO_CHANNEL_EXT
);
577 tmp
= b43legacy_radio_read16(dev
, 0x007A);
578 tmp
&= (phy
->rev
>= 5) ? 0x007F : 0x000F;
579 b43legacy_radio_write16(dev
, 0x007A, tmp
);
580 b43legacy_phy_write(dev
, 0x0030, 0x00FF);
581 b43legacy_write16(dev
, 0x03EC, 0x7F7F);
582 b43legacy_phy_write(dev
, 0x0026, 0x0000);
583 b43legacy_phy_write(dev
, 0x0015,
584 b43legacy_phy_read(dev
, 0x0015) | 0x0020);
585 b43legacy_phy_write(dev
, 0x002A, 0x08A3);
586 b43legacy_radio_write16(dev
, 0x007A,
587 b43legacy_radio_read16(dev
, 0x007A)
590 nrssi0
= (s16
)b43legacy_phy_read(dev
, 0x0027);
591 b43legacy_radio_write16(dev
, 0x007A,
592 b43legacy_radio_read16(dev
, 0x007A)
594 if (phy
->analog
>= 2)
595 b43legacy_write16(dev
, 0x03E6, 0x0040);
596 else if (phy
->analog
== 0)
597 b43legacy_write16(dev
, 0x03E6, 0x0122);
599 b43legacy_write16(dev
, B43legacy_MMIO_CHANNEL_EXT
,
600 b43legacy_read16(dev
,
601 B43legacy_MMIO_CHANNEL_EXT
) & 0x2000);
602 b43legacy_phy_write(dev
, 0x0020, 0x3F3F);
603 b43legacy_phy_write(dev
, 0x0015, 0xF330);
604 b43legacy_radio_write16(dev
, 0x005A, 0x0060);
605 b43legacy_radio_write16(dev
, 0x0043,
606 b43legacy_radio_read16(dev
, 0x0043)
608 b43legacy_phy_write(dev
, 0x005A, 0x0480);
609 b43legacy_phy_write(dev
, 0x0059, 0x0810);
610 b43legacy_phy_write(dev
, 0x0058, 0x000D);
613 nrssi1
= (s16
)b43legacy_phy_read(dev
, 0x0027);
614 b43legacy_phy_write(dev
, 0x0030, backup
[3]);
615 b43legacy_radio_write16(dev
, 0x007A, backup
[0]);
616 b43legacy_write16(dev
, 0x03E2, backup
[11]);
617 b43legacy_phy_write(dev
, 0x0026, backup
[4]);
618 b43legacy_phy_write(dev
, 0x0015, backup
[5]);
619 b43legacy_phy_write(dev
, 0x002A, backup
[6]);
620 b43legacy_synth_pu_workaround(dev
, phy
->channel
);
621 if (phy
->analog
!= 0)
622 b43legacy_write16(dev
, 0x03F4, backup
[13]);
624 b43legacy_phy_write(dev
, 0x0020, backup
[7]);
625 b43legacy_phy_write(dev
, 0x005A, backup
[8]);
626 b43legacy_phy_write(dev
, 0x0059, backup
[9]);
627 b43legacy_phy_write(dev
, 0x0058, backup
[10]);
628 b43legacy_radio_write16(dev
, 0x0052, backup
[1]);
629 b43legacy_radio_write16(dev
, 0x0043, backup
[2]);
631 if (nrssi0
== nrssi1
)
632 phy
->nrssislope
= 0x00010000;
634 phy
->nrssislope
= 0x00400000 / (nrssi0
- nrssi1
);
637 phy
->nrssi
[0] = nrssi0
;
638 phy
->nrssi
[1] = nrssi1
;
641 case B43legacy_PHYTYPE_G
:
642 if (phy
->radio_rev
>= 9)
644 if (phy
->radio_rev
== 8)
645 b43legacy_calc_nrssi_offset(dev
);
647 b43legacy_phy_write(dev
, B43legacy_PHY_G_CRS
,
648 b43legacy_phy_read(dev
, B43legacy_PHY_G_CRS
)
650 b43legacy_phy_write(dev
, 0x0802,
651 b43legacy_phy_read(dev
, 0x0802) & 0xFFFC);
652 backup
[7] = b43legacy_read16(dev
, 0x03E2);
653 b43legacy_write16(dev
, 0x03E2,
654 b43legacy_read16(dev
, 0x03E2) | 0x8000);
655 backup
[0] = b43legacy_radio_read16(dev
, 0x007A);
656 backup
[1] = b43legacy_radio_read16(dev
, 0x0052);
657 backup
[2] = b43legacy_radio_read16(dev
, 0x0043);
658 backup
[3] = b43legacy_phy_read(dev
, 0x0015);
659 backup
[4] = b43legacy_phy_read(dev
, 0x005A);
660 backup
[5] = b43legacy_phy_read(dev
, 0x0059);
661 backup
[6] = b43legacy_phy_read(dev
, 0x0058);
662 backup
[8] = b43legacy_read16(dev
, 0x03E6);
663 backup
[9] = b43legacy_read16(dev
, B43legacy_MMIO_CHANNEL_EXT
);
665 backup
[10] = b43legacy_phy_read(dev
, 0x002E);
666 backup
[11] = b43legacy_phy_read(dev
, 0x002F);
667 backup
[12] = b43legacy_phy_read(dev
, 0x080F);
668 backup
[13] = b43legacy_phy_read(dev
,
669 B43legacy_PHY_G_LO_CONTROL
);
670 backup
[14] = b43legacy_phy_read(dev
, 0x0801);
671 backup
[15] = b43legacy_phy_read(dev
, 0x0060);
672 backup
[16] = b43legacy_phy_read(dev
, 0x0014);
673 backup
[17] = b43legacy_phy_read(dev
, 0x0478);
674 b43legacy_phy_write(dev
, 0x002E, 0);
675 b43legacy_phy_write(dev
, B43legacy_PHY_G_LO_CONTROL
, 0);
677 case 4: case 6: case 7:
678 b43legacy_phy_write(dev
, 0x0478,
679 b43legacy_phy_read(dev
,
681 b43legacy_phy_write(dev
, 0x0801,
682 b43legacy_phy_read(dev
,
686 b43legacy_phy_write(dev
, 0x0801,
687 b43legacy_phy_read(dev
,
691 b43legacy_phy_write(dev
, 0x0060,
692 b43legacy_phy_read(dev
, 0x0060)
694 b43legacy_phy_write(dev
, 0x0014,
695 b43legacy_phy_read(dev
, 0x0014)
698 b43legacy_radio_write16(dev
, 0x007A,
699 b43legacy_radio_read16(dev
, 0x007A)
701 b43legacy_set_all_gains(dev
, 0, 8, 0);
702 b43legacy_radio_write16(dev
, 0x007A,
703 b43legacy_radio_read16(dev
, 0x007A)
706 b43legacy_phy_write(dev
, 0x0811,
707 (b43legacy_phy_read(dev
, 0x0811)
709 b43legacy_phy_write(dev
, 0x0812,
710 (b43legacy_phy_read(dev
, 0x0812)
713 b43legacy_radio_write16(dev
, 0x007A,
714 b43legacy_radio_read16(dev
, 0x007A)
718 nrssi0
= (s16
)((b43legacy_phy_read(dev
, 0x047F) >> 8) & 0x003F);
719 if (nrssi0
>= 0x0020)
722 b43legacy_radio_write16(dev
, 0x007A,
723 b43legacy_radio_read16(dev
, 0x007A)
725 if (phy
->analog
>= 2)
726 b43legacy_phy_write(dev
, 0x0003,
727 (b43legacy_phy_read(dev
, 0x0003)
730 b43legacy_write16(dev
, B43legacy_MMIO_CHANNEL_EXT
,
731 b43legacy_read16(dev
,
732 B43legacy_MMIO_CHANNEL_EXT
) | 0x2000);
733 b43legacy_radio_write16(dev
, 0x007A,
734 b43legacy_radio_read16(dev
, 0x007A)
736 b43legacy_phy_write(dev
, 0x0015, 0xF330);
738 b43legacy_phy_write(dev
, 0x0812,
739 (b43legacy_phy_read(dev
, 0x0812)
741 b43legacy_phy_write(dev
, 0x0811,
742 (b43legacy_phy_read(dev
, 0x0811)
746 b43legacy_set_all_gains(dev
, 3, 0, 1);
747 if (phy
->radio_rev
== 8)
748 b43legacy_radio_write16(dev
, 0x0043, 0x001F);
750 tmp
= b43legacy_radio_read16(dev
, 0x0052) & 0xFF0F;
751 b43legacy_radio_write16(dev
, 0x0052, tmp
| 0x0060);
752 tmp
= b43legacy_radio_read16(dev
, 0x0043) & 0xFFF0;
753 b43legacy_radio_write16(dev
, 0x0043, tmp
| 0x0009);
755 b43legacy_phy_write(dev
, 0x005A, 0x0480);
756 b43legacy_phy_write(dev
, 0x0059, 0x0810);
757 b43legacy_phy_write(dev
, 0x0058, 0x000D);
759 nrssi1
= (s16
)((b43legacy_phy_read(dev
, 0x047F) >> 8) & 0x003F);
760 if (nrssi1
>= 0x0020)
762 if (nrssi0
== nrssi1
)
763 phy
->nrssislope
= 0x00010000;
765 phy
->nrssislope
= 0x00400000 / (nrssi0
- nrssi1
);
767 phy
->nrssi
[0] = nrssi1
;
768 phy
->nrssi
[1] = nrssi0
;
771 b43legacy_phy_write(dev
, 0x002E, backup
[10]);
772 b43legacy_phy_write(dev
, 0x002F, backup
[11]);
773 b43legacy_phy_write(dev
, 0x080F, backup
[12]);
774 b43legacy_phy_write(dev
, B43legacy_PHY_G_LO_CONTROL
,
778 b43legacy_phy_write(dev
, 0x0812,
779 b43legacy_phy_read(dev
, 0x0812)
781 b43legacy_phy_write(dev
, 0x0811,
782 b43legacy_phy_read(dev
, 0x0811)
786 b43legacy_radio_write16(dev
, 0x007A, backup
[0]);
787 b43legacy_radio_write16(dev
, 0x0052, backup
[1]);
788 b43legacy_radio_write16(dev
, 0x0043, backup
[2]);
789 b43legacy_write16(dev
, 0x03E2, backup
[7]);
790 b43legacy_write16(dev
, 0x03E6, backup
[8]);
791 b43legacy_write16(dev
, B43legacy_MMIO_CHANNEL_EXT
, backup
[9]);
792 b43legacy_phy_write(dev
, 0x0015, backup
[3]);
793 b43legacy_phy_write(dev
, 0x005A, backup
[4]);
794 b43legacy_phy_write(dev
, 0x0059, backup
[5]);
795 b43legacy_phy_write(dev
, 0x0058, backup
[6]);
796 b43legacy_synth_pu_workaround(dev
, phy
->channel
);
797 b43legacy_phy_write(dev
, 0x0802,
798 b43legacy_phy_read(dev
, 0x0802) | 0x0003);
799 b43legacy_set_original_gains(dev
);
800 b43legacy_phy_write(dev
, B43legacy_PHY_G_CRS
,
801 b43legacy_phy_read(dev
, B43legacy_PHY_G_CRS
)
804 b43legacy_phy_write(dev
, 0x0801, backup
[14]);
805 b43legacy_phy_write(dev
, 0x0060, backup
[15]);
806 b43legacy_phy_write(dev
, 0x0014, backup
[16]);
807 b43legacy_phy_write(dev
, 0x0478, backup
[17]);
809 b43legacy_nrssi_mem_update(dev
);
810 b43legacy_calc_nrssi_threshold(dev
);
817 void b43legacy_calc_nrssi_threshold(struct b43legacy_wldev
*dev
)
819 struct b43legacy_phy
*phy
= &dev
->phy
;
827 case B43legacy_PHYTYPE_B
: {
828 if (phy
->radio_ver
!= 0x2050)
830 if (!(dev
->dev
->bus
->sprom
.r1
.boardflags_lo
&
834 if (phy
->radio_rev
>= 6) {
835 threshold
= (phy
->nrssi
[1] - phy
->nrssi
[0]) * 32;
836 threshold
+= 20 * (phy
->nrssi
[0] + 1);
839 threshold
= phy
->nrssi
[1] - 5;
841 threshold
= limit_value(threshold
, 0, 0x3E);
842 b43legacy_phy_read(dev
, 0x0020); /* dummy read */
843 b43legacy_phy_write(dev
, 0x0020, (((u16
)threshold
) << 8)
846 if (phy
->radio_rev
>= 6) {
847 b43legacy_phy_write(dev
, 0x0087, 0x0E0D);
848 b43legacy_phy_write(dev
, 0x0086, 0x0C0B);
849 b43legacy_phy_write(dev
, 0x0085, 0x0A09);
850 b43legacy_phy_write(dev
, 0x0084, 0x0808);
851 b43legacy_phy_write(dev
, 0x0083, 0x0808);
852 b43legacy_phy_write(dev
, 0x0082, 0x0604);
853 b43legacy_phy_write(dev
, 0x0081, 0x0302);
854 b43legacy_phy_write(dev
, 0x0080, 0x0100);
858 case B43legacy_PHYTYPE_G
:
860 !(dev
->dev
->bus
->sprom
.r1
.boardflags_lo
&
861 B43legacy_BFL_RSSI
)) {
862 tmp16
= b43legacy_nrssi_hw_read(dev
, 0x20);
866 b43legacy_phy_write(dev
, 0x048A,
867 (b43legacy_phy_read(dev
,
868 0x048A) & 0xF000) | 0x09EB);
870 b43legacy_phy_write(dev
, 0x048A,
871 (b43legacy_phy_read(dev
,
872 0x048A) & 0xF000) | 0x0AED);
874 if (phy
->interfmode
==
875 B43legacy_RADIO_INTERFMODE_NONWLAN
) {
878 } else if (!phy
->aci_wlan_automatic
&&
887 a
= a
* (phy
->nrssi
[1] - phy
->nrssi
[0]);
888 a
+= (phy
->nrssi
[0] << 6);
894 a
= limit_value(a
, -31, 31);
896 b
= b
* (phy
->nrssi
[1] - phy
->nrssi
[0]);
897 b
+= (phy
->nrssi
[0] << 6);
903 b
= limit_value(b
, -31, 31);
905 tmp_u16
= b43legacy_phy_read(dev
, 0x048A) & 0xF000;
906 tmp_u16
|= ((u32
)b
& 0x0000003F);
907 tmp_u16
|= (((u32
)a
& 0x0000003F) << 6);
908 b43legacy_phy_write(dev
, 0x048A, tmp_u16
);
916 /* Stack implementation to save/restore values from the
917 * interference mitigation code.
918 * It is save to restore values in random order.
920 static void _stack_save(u32
*_stackptr
, size_t *stackidx
,
921 u8 id
, u16 offset
, u16 value
)
923 u32
*stackptr
= &(_stackptr
[*stackidx
]);
925 B43legacy_WARN_ON(!((offset
& 0xE000) == 0x0000));
926 B43legacy_WARN_ON(!((id
& 0xF8) == 0x00));
928 *stackptr
|= ((u32
)id
) << 13;
929 *stackptr
|= ((u32
)value
) << 16;
931 B43legacy_WARN_ON(!(*stackidx
< B43legacy_INTERFSTACK_SIZE
));
934 static u16
_stack_restore(u32
*stackptr
,
939 B43legacy_WARN_ON(!((offset
& 0xE000) == 0x0000));
940 B43legacy_WARN_ON(!((id
& 0xF8) == 0x00));
941 for (i
= 0; i
< B43legacy_INTERFSTACK_SIZE
; i
++, stackptr
++) {
942 if ((*stackptr
& 0x00001FFF) != offset
)
944 if (((*stackptr
& 0x00007000) >> 13) != id
)
946 return ((*stackptr
& 0xFFFF0000) >> 16);
953 #define phy_stacksave(offset) \
955 _stack_save(stack, &stackidx, 0x1, (offset), \
956 b43legacy_phy_read(dev, (offset))); \
958 #define phy_stackrestore(offset) \
960 b43legacy_phy_write(dev, (offset), \
961 _stack_restore(stack, 0x1, \
964 #define radio_stacksave(offset) \
966 _stack_save(stack, &stackidx, 0x2, (offset), \
967 b43legacy_radio_read16(dev, (offset))); \
969 #define radio_stackrestore(offset) \
971 b43legacy_radio_write16(dev, (offset), \
972 _stack_restore(stack, 0x2, \
975 #define ilt_stacksave(offset) \
977 _stack_save(stack, &stackidx, 0x3, (offset), \
978 b43legacy_ilt_read(dev, (offset))); \
980 #define ilt_stackrestore(offset) \
982 b43legacy_ilt_write(dev, (offset), \
983 _stack_restore(stack, 0x3, \
988 b43legacy_radio_interference_mitigation_enable(struct b43legacy_wldev
*dev
,
991 struct b43legacy_phy
*phy
= &dev
->phy
;
996 u32
*stack
= phy
->interfstack
;
999 case B43legacy_RADIO_INTERFMODE_NONWLAN
:
1000 if (phy
->rev
!= 1) {
1001 b43legacy_phy_write(dev
, 0x042B,
1002 b43legacy_phy_read(dev
, 0x042B)
1004 b43legacy_phy_write(dev
, B43legacy_PHY_G_CRS
,
1005 b43legacy_phy_read(dev
,
1006 B43legacy_PHY_G_CRS
) & ~0x4000);
1009 radio_stacksave(0x0078);
1010 tmp
= (b43legacy_radio_read16(dev
, 0x0078) & 0x001E);
1011 flipped
= flip_4bit(tmp
);
1012 if (flipped
< 10 && flipped
>= 8)
1014 else if (flipped
>= 10)
1016 flipped
= flip_4bit(flipped
);
1017 flipped
= (flipped
<< 1) | 0x0020;
1018 b43legacy_radio_write16(dev
, 0x0078, flipped
);
1020 b43legacy_calc_nrssi_threshold(dev
);
1022 phy_stacksave(0x0406);
1023 b43legacy_phy_write(dev
, 0x0406, 0x7E28);
1025 b43legacy_phy_write(dev
, 0x042B,
1026 b43legacy_phy_read(dev
, 0x042B) | 0x0800);
1027 b43legacy_phy_write(dev
, B43legacy_PHY_RADIO_BITFIELD
,
1028 b43legacy_phy_read(dev
,
1029 B43legacy_PHY_RADIO_BITFIELD
) | 0x1000);
1031 phy_stacksave(0x04A0);
1032 b43legacy_phy_write(dev
, 0x04A0,
1033 (b43legacy_phy_read(dev
, 0x04A0) & 0xC0C0)
1035 phy_stacksave(0x04A1);
1036 b43legacy_phy_write(dev
, 0x04A1,
1037 (b43legacy_phy_read(dev
, 0x04A1) & 0xC0C0)
1039 phy_stacksave(0x04A2);
1040 b43legacy_phy_write(dev
, 0x04A2,
1041 (b43legacy_phy_read(dev
, 0x04A2) & 0xC0C0)
1043 phy_stacksave(0x04A8);
1044 b43legacy_phy_write(dev
, 0x04A8,
1045 (b43legacy_phy_read(dev
, 0x04A8) & 0xC0C0)
1047 phy_stacksave(0x04AB);
1048 b43legacy_phy_write(dev
, 0x04AB,
1049 (b43legacy_phy_read(dev
, 0x04AB) & 0xC0C0)
1052 phy_stacksave(0x04A7);
1053 b43legacy_phy_write(dev
, 0x04A7, 0x0002);
1054 phy_stacksave(0x04A3);
1055 b43legacy_phy_write(dev
, 0x04A3, 0x287A);
1056 phy_stacksave(0x04A9);
1057 b43legacy_phy_write(dev
, 0x04A9, 0x2027);
1058 phy_stacksave(0x0493);
1059 b43legacy_phy_write(dev
, 0x0493, 0x32F5);
1060 phy_stacksave(0x04AA);
1061 b43legacy_phy_write(dev
, 0x04AA, 0x2027);
1062 phy_stacksave(0x04AC);
1063 b43legacy_phy_write(dev
, 0x04AC, 0x32F5);
1065 case B43legacy_RADIO_INTERFMODE_MANUALWLAN
:
1066 if (b43legacy_phy_read(dev
, 0x0033) & 0x0800)
1069 phy
->aci_enable
= 1;
1071 phy_stacksave(B43legacy_PHY_RADIO_BITFIELD
);
1072 phy_stacksave(B43legacy_PHY_G_CRS
);
1074 phy_stacksave(0x0406);
1076 phy_stacksave(0x04C0);
1077 phy_stacksave(0x04C1);
1079 phy_stacksave(0x0033);
1080 phy_stacksave(0x04A7);
1081 phy_stacksave(0x04A3);
1082 phy_stacksave(0x04A9);
1083 phy_stacksave(0x04AA);
1084 phy_stacksave(0x04AC);
1085 phy_stacksave(0x0493);
1086 phy_stacksave(0x04A1);
1087 phy_stacksave(0x04A0);
1088 phy_stacksave(0x04A2);
1089 phy_stacksave(0x048A);
1090 phy_stacksave(0x04A8);
1091 phy_stacksave(0x04AB);
1092 if (phy
->rev
== 2) {
1093 phy_stacksave(0x04AD);
1094 phy_stacksave(0x04AE);
1095 } else if (phy
->rev
>= 3) {
1096 phy_stacksave(0x04AD);
1097 phy_stacksave(0x0415);
1098 phy_stacksave(0x0416);
1099 phy_stacksave(0x0417);
1100 ilt_stacksave(0x1A00 + 0x2);
1101 ilt_stacksave(0x1A00 + 0x3);
1103 phy_stacksave(0x042B);
1104 phy_stacksave(0x048C);
1106 b43legacy_phy_write(dev
, B43legacy_PHY_RADIO_BITFIELD
,
1107 b43legacy_phy_read(dev
,
1108 B43legacy_PHY_RADIO_BITFIELD
) & ~0x1000);
1109 b43legacy_phy_write(dev
, B43legacy_PHY_G_CRS
,
1110 (b43legacy_phy_read(dev
,
1111 B43legacy_PHY_G_CRS
)
1112 & 0xFFFC) | 0x0002);
1114 b43legacy_phy_write(dev
, 0x0033, 0x0800);
1115 b43legacy_phy_write(dev
, 0x04A3, 0x2027);
1116 b43legacy_phy_write(dev
, 0x04A9, 0x1CA8);
1117 b43legacy_phy_write(dev
, 0x0493, 0x287A);
1118 b43legacy_phy_write(dev
, 0x04AA, 0x1CA8);
1119 b43legacy_phy_write(dev
, 0x04AC, 0x287A);
1121 b43legacy_phy_write(dev
, 0x04A0,
1122 (b43legacy_phy_read(dev
, 0x04A0)
1123 & 0xFFC0) | 0x001A);
1124 b43legacy_phy_write(dev
, 0x04A7, 0x000D);
1127 b43legacy_phy_write(dev
, 0x0406, 0xFF0D);
1128 else if (phy
->rev
== 2) {
1129 b43legacy_phy_write(dev
, 0x04C0, 0xFFFF);
1130 b43legacy_phy_write(dev
, 0x04C1, 0x00A9);
1132 b43legacy_phy_write(dev
, 0x04C0, 0x00C1);
1133 b43legacy_phy_write(dev
, 0x04C1, 0x0059);
1136 b43legacy_phy_write(dev
, 0x04A1,
1137 (b43legacy_phy_read(dev
, 0x04A1)
1138 & 0xC0FF) | 0x1800);
1139 b43legacy_phy_write(dev
, 0x04A1,
1140 (b43legacy_phy_read(dev
, 0x04A1)
1141 & 0xFFC0) | 0x0015);
1142 b43legacy_phy_write(dev
, 0x04A8,
1143 (b43legacy_phy_read(dev
, 0x04A8)
1144 & 0xCFFF) | 0x1000);
1145 b43legacy_phy_write(dev
, 0x04A8,
1146 (b43legacy_phy_read(dev
, 0x04A8)
1147 & 0xF0FF) | 0x0A00);
1148 b43legacy_phy_write(dev
, 0x04AB,
1149 (b43legacy_phy_read(dev
, 0x04AB)
1150 & 0xCFFF) | 0x1000);
1151 b43legacy_phy_write(dev
, 0x04AB,
1152 (b43legacy_phy_read(dev
, 0x04AB)
1153 & 0xF0FF) | 0x0800);
1154 b43legacy_phy_write(dev
, 0x04AB,
1155 (b43legacy_phy_read(dev
, 0x04AB)
1156 & 0xFFCF) | 0x0010);
1157 b43legacy_phy_write(dev
, 0x04AB,
1158 (b43legacy_phy_read(dev
, 0x04AB)
1159 & 0xFFF0) | 0x0005);
1160 b43legacy_phy_write(dev
, 0x04A8,
1161 (b43legacy_phy_read(dev
, 0x04A8)
1162 & 0xFFCF) | 0x0010);
1163 b43legacy_phy_write(dev
, 0x04A8,
1164 (b43legacy_phy_read(dev
, 0x04A8)
1165 & 0xFFF0) | 0x0006);
1166 b43legacy_phy_write(dev
, 0x04A2,
1167 (b43legacy_phy_read(dev
, 0x04A2)
1168 & 0xF0FF) | 0x0800);
1169 b43legacy_phy_write(dev
, 0x04A0,
1170 (b43legacy_phy_read(dev
, 0x04A0)
1171 & 0xF0FF) | 0x0500);
1172 b43legacy_phy_write(dev
, 0x04A2,
1173 (b43legacy_phy_read(dev
, 0x04A2)
1174 & 0xFFF0) | 0x000B);
1176 if (phy
->rev
>= 3) {
1177 b43legacy_phy_write(dev
, 0x048A,
1178 b43legacy_phy_read(dev
, 0x048A)
1180 b43legacy_phy_write(dev
, 0x0415,
1181 (b43legacy_phy_read(dev
, 0x0415)
1182 & 0x8000) | 0x36D8);
1183 b43legacy_phy_write(dev
, 0x0416,
1184 (b43legacy_phy_read(dev
, 0x0416)
1185 & 0x8000) | 0x36D8);
1186 b43legacy_phy_write(dev
, 0x0417,
1187 (b43legacy_phy_read(dev
, 0x0417)
1188 & 0xFE00) | 0x016D);
1190 b43legacy_phy_write(dev
, 0x048A,
1191 b43legacy_phy_read(dev
, 0x048A)
1193 b43legacy_phy_write(dev
, 0x048A,
1194 (b43legacy_phy_read(dev
, 0x048A)
1195 & 0x9FFF) | 0x2000);
1196 tmp32
= b43legacy_shm_read32(dev
, B43legacy_SHM_SHARED
,
1197 B43legacy_UCODEFLAGS_OFFSET
);
1198 if (!(tmp32
& 0x800)) {
1200 b43legacy_shm_write32(dev
, B43legacy_SHM_SHARED
,
1201 B43legacy_UCODEFLAGS_OFFSET
,
1206 b43legacy_phy_write(dev
, 0x042B,
1207 b43legacy_phy_read(dev
, 0x042B)
1209 b43legacy_phy_write(dev
, 0x048C,
1210 (b43legacy_phy_read(dev
, 0x048C)
1211 & 0xF0FF) | 0x0200);
1212 if (phy
->rev
== 2) {
1213 b43legacy_phy_write(dev
, 0x04AE,
1214 (b43legacy_phy_read(dev
, 0x04AE)
1215 & 0xFF00) | 0x007F);
1216 b43legacy_phy_write(dev
, 0x04AD,
1217 (b43legacy_phy_read(dev
, 0x04AD)
1218 & 0x00FF) | 0x1300);
1219 } else if (phy
->rev
>= 6) {
1220 b43legacy_ilt_write(dev
, 0x1A00 + 0x3, 0x007F);
1221 b43legacy_ilt_write(dev
, 0x1A00 + 0x2, 0x007F);
1222 b43legacy_phy_write(dev
, 0x04AD,
1223 b43legacy_phy_read(dev
, 0x04AD)
1226 b43legacy_calc_nrssi_slope(dev
);
1229 B43legacy_BUG_ON(1);
1234 b43legacy_radio_interference_mitigation_disable(struct b43legacy_wldev
*dev
,
1237 struct b43legacy_phy
*phy
= &dev
->phy
;
1239 u32
*stack
= phy
->interfstack
;
1242 case B43legacy_RADIO_INTERFMODE_NONWLAN
:
1243 if (phy
->rev
!= 1) {
1244 b43legacy_phy_write(dev
, 0x042B,
1245 b43legacy_phy_read(dev
, 0x042B)
1247 b43legacy_phy_write(dev
, B43legacy_PHY_G_CRS
,
1248 b43legacy_phy_read(dev
,
1249 B43legacy_PHY_G_CRS
) | 0x4000);
1252 phy_stackrestore(0x0078);
1253 b43legacy_calc_nrssi_threshold(dev
);
1254 phy_stackrestore(0x0406);
1255 b43legacy_phy_write(dev
, 0x042B,
1256 b43legacy_phy_read(dev
, 0x042B) & ~0x0800);
1257 if (!dev
->bad_frames_preempt
)
1258 b43legacy_phy_write(dev
, B43legacy_PHY_RADIO_BITFIELD
,
1259 b43legacy_phy_read(dev
,
1260 B43legacy_PHY_RADIO_BITFIELD
)
1262 b43legacy_phy_write(dev
, B43legacy_PHY_G_CRS
,
1263 b43legacy_phy_read(dev
, B43legacy_PHY_G_CRS
)
1265 phy_stackrestore(0x04A0);
1266 phy_stackrestore(0x04A1);
1267 phy_stackrestore(0x04A2);
1268 phy_stackrestore(0x04A8);
1269 phy_stackrestore(0x04AB);
1270 phy_stackrestore(0x04A7);
1271 phy_stackrestore(0x04A3);
1272 phy_stackrestore(0x04A9);
1273 phy_stackrestore(0x0493);
1274 phy_stackrestore(0x04AA);
1275 phy_stackrestore(0x04AC);
1277 case B43legacy_RADIO_INTERFMODE_MANUALWLAN
:
1278 if (!(b43legacy_phy_read(dev
, 0x0033) & 0x0800))
1281 phy
->aci_enable
= 0;
1283 phy_stackrestore(B43legacy_PHY_RADIO_BITFIELD
);
1284 phy_stackrestore(B43legacy_PHY_G_CRS
);
1285 phy_stackrestore(0x0033);
1286 phy_stackrestore(0x04A3);
1287 phy_stackrestore(0x04A9);
1288 phy_stackrestore(0x0493);
1289 phy_stackrestore(0x04AA);
1290 phy_stackrestore(0x04AC);
1291 phy_stackrestore(0x04A0);
1292 phy_stackrestore(0x04A7);
1293 if (phy
->rev
>= 2) {
1294 phy_stackrestore(0x04C0);
1295 phy_stackrestore(0x04C1);
1297 phy_stackrestore(0x0406);
1298 phy_stackrestore(0x04A1);
1299 phy_stackrestore(0x04AB);
1300 phy_stackrestore(0x04A8);
1301 if (phy
->rev
== 2) {
1302 phy_stackrestore(0x04AD);
1303 phy_stackrestore(0x04AE);
1304 } else if (phy
->rev
>= 3) {
1305 phy_stackrestore(0x04AD);
1306 phy_stackrestore(0x0415);
1307 phy_stackrestore(0x0416);
1308 phy_stackrestore(0x0417);
1309 ilt_stackrestore(0x1A00 + 0x2);
1310 ilt_stackrestore(0x1A00 + 0x3);
1312 phy_stackrestore(0x04A2);
1313 phy_stackrestore(0x04A8);
1314 phy_stackrestore(0x042B);
1315 phy_stackrestore(0x048C);
1316 tmp32
= b43legacy_shm_read32(dev
, B43legacy_SHM_SHARED
,
1317 B43legacy_UCODEFLAGS_OFFSET
);
1318 if (tmp32
& 0x800) {
1320 b43legacy_shm_write32(dev
, B43legacy_SHM_SHARED
,
1321 B43legacy_UCODEFLAGS_OFFSET
,
1324 b43legacy_calc_nrssi_slope(dev
);
1327 B43legacy_BUG_ON(1);
1331 #undef phy_stacksave
1332 #undef phy_stackrestore
1333 #undef radio_stacksave
1334 #undef radio_stackrestore
1335 #undef ilt_stacksave
1336 #undef ilt_stackrestore
1338 int b43legacy_radio_set_interference_mitigation(struct b43legacy_wldev
*dev
,
1341 struct b43legacy_phy
*phy
= &dev
->phy
;
1344 if ((phy
->type
!= B43legacy_PHYTYPE_G
) ||
1345 (phy
->rev
== 0) || (!phy
->gmode
))
1348 phy
->aci_wlan_automatic
= 0;
1350 case B43legacy_RADIO_INTERFMODE_AUTOWLAN
:
1351 phy
->aci_wlan_automatic
= 1;
1352 if (phy
->aci_enable
)
1353 mode
= B43legacy_RADIO_INTERFMODE_MANUALWLAN
;
1355 mode
= B43legacy_RADIO_INTERFMODE_NONE
;
1357 case B43legacy_RADIO_INTERFMODE_NONE
:
1358 case B43legacy_RADIO_INTERFMODE_NONWLAN
:
1359 case B43legacy_RADIO_INTERFMODE_MANUALWLAN
:
1365 currentmode
= phy
->interfmode
;
1366 if (currentmode
== mode
)
1368 if (currentmode
!= B43legacy_RADIO_INTERFMODE_NONE
)
1369 b43legacy_radio_interference_mitigation_disable(dev
,
1372 if (mode
== B43legacy_RADIO_INTERFMODE_NONE
) {
1373 phy
->aci_enable
= 0;
1374 phy
->aci_hw_rssi
= 0;
1376 b43legacy_radio_interference_mitigation_enable(dev
, mode
);
1377 phy
->interfmode
= mode
;
1382 u16
b43legacy_radio_calibrationvalue(struct b43legacy_wldev
*dev
)
1388 reg
= b43legacy_radio_read16(dev
, 0x0060);
1389 index
= (reg
& 0x001E) >> 1;
1390 ret
= rcc_table
[index
] << 1;
1391 ret
|= (reg
& 0x0001);
1397 #define LPD(L, P, D) (((L) << 2) | ((P) << 1) | ((D) << 0))
1398 static u16
b43legacy_get_812_value(struct b43legacy_wldev
*dev
, u8 lpd
)
1400 struct b43legacy_phy
*phy
= &dev
->phy
;
1402 u16 adj_loopback_gain
= phy
->loopback_gain
[0];
1404 u16 extern_lna_control
;
1408 if (!has_loopback_gain(phy
)) {
1409 if (phy
->rev
< 7 || !(dev
->dev
->bus
->sprom
.r1
.boardflags_lo
1410 & B43legacy_BFL_EXTLNA
)) {
1421 B43legacy_BUG_ON(1);
1434 B43legacy_BUG_ON(1);
1438 if (phy
->radio_rev
== 8)
1439 adj_loopback_gain
+= 0x003E;
1441 adj_loopback_gain
+= 0x0026;
1442 if (adj_loopback_gain
>= 0x46) {
1443 adj_loopback_gain
-= 0x46;
1444 extern_lna_control
= 0x3000;
1445 } else if (adj_loopback_gain
>= 0x3A) {
1446 adj_loopback_gain
-= 0x3A;
1447 extern_lna_control
= 0x2000;
1448 } else if (adj_loopback_gain
>= 0x2E) {
1449 adj_loopback_gain
-= 0x2E;
1450 extern_lna_control
= 0x1000;
1452 adj_loopback_gain
-= 0x10;
1453 extern_lna_control
= 0x0000;
1455 for (loop
= 0; loop
< 16; loop
++) {
1456 u16 tmp
= adj_loopback_gain
- 6 * loop
;
1461 loop_or
= (loop
<< 8) | extern_lna_control
;
1462 if (phy
->rev
>= 7 && dev
->dev
->bus
->sprom
.r1
.boardflags_lo
1463 & B43legacy_BFL_EXTLNA
) {
1464 if (extern_lna_control
)
1470 return (0x8092 | loop_or
);
1472 return (0x2092 | loop_or
);
1474 return (0x2093 | loop_or
);
1476 B43legacy_BUG_ON(1);
1484 return (0x0092 | loop_or
);
1486 return (0x0093 | loop_or
);
1488 B43legacy_BUG_ON(1);
1495 u16
b43legacy_radio_init2050(struct b43legacy_wldev
*dev
)
1497 struct b43legacy_phy
*phy
= &dev
->phy
;
1498 u16 backup
[21] = { 0 };
1505 backup
[0] = b43legacy_radio_read16(dev
, 0x0043);
1506 backup
[14] = b43legacy_radio_read16(dev
, 0x0051);
1507 backup
[15] = b43legacy_radio_read16(dev
, 0x0052);
1508 backup
[1] = b43legacy_phy_read(dev
, 0x0015);
1509 backup
[16] = b43legacy_phy_read(dev
, 0x005A);
1510 backup
[17] = b43legacy_phy_read(dev
, 0x0059);
1511 backup
[18] = b43legacy_phy_read(dev
, 0x0058);
1512 if (phy
->type
== B43legacy_PHYTYPE_B
) {
1513 backup
[2] = b43legacy_phy_read(dev
, 0x0030);
1514 backup
[3] = b43legacy_read16(dev
, 0x03EC);
1515 b43legacy_phy_write(dev
, 0x0030, 0x00FF);
1516 b43legacy_write16(dev
, 0x03EC, 0x3F3F);
1519 backup
[4] = b43legacy_phy_read(dev
, 0x0811);
1520 backup
[5] = b43legacy_phy_read(dev
, 0x0812);
1521 backup
[6] = b43legacy_phy_read(dev
, 0x0814);
1522 backup
[7] = b43legacy_phy_read(dev
, 0x0815);
1523 backup
[8] = b43legacy_phy_read(dev
,
1524 B43legacy_PHY_G_CRS
);
1525 backup
[9] = b43legacy_phy_read(dev
, 0x0802);
1526 b43legacy_phy_write(dev
, 0x0814,
1527 (b43legacy_phy_read(dev
, 0x0814)
1529 b43legacy_phy_write(dev
, 0x0815,
1530 (b43legacy_phy_read(dev
, 0x0815)
1532 b43legacy_phy_write(dev
, B43legacy_PHY_G_CRS
,
1533 (b43legacy_phy_read(dev
,
1534 B43legacy_PHY_G_CRS
) & 0x7FFF));
1535 b43legacy_phy_write(dev
, 0x0802,
1536 (b43legacy_phy_read(dev
, 0x0802)
1538 if (phy
->rev
> 1) { /* loopback gain enabled */
1539 backup
[19] = b43legacy_phy_read(dev
, 0x080F);
1540 backup
[20] = b43legacy_phy_read(dev
, 0x0810);
1542 b43legacy_phy_write(dev
, 0x080F,
1545 b43legacy_phy_write(dev
, 0x080F,
1547 b43legacy_phy_write(dev
, 0x0810, 0x0000);
1549 b43legacy_phy_write(dev
, 0x0812,
1550 b43legacy_get_812_value(dev
,
1553 !(dev
->dev
->bus
->sprom
.r1
.boardflags_lo
1554 & B43legacy_BFL_EXTLNA
))
1555 b43legacy_phy_write(dev
, 0x0811, 0x01B3);
1557 b43legacy_phy_write(dev
, 0x0811, 0x09B3);
1560 b43legacy_write16(dev
, B43legacy_MMIO_PHY_RADIO
,
1561 (b43legacy_read16(dev
, B43legacy_MMIO_PHY_RADIO
)
1563 backup
[10] = b43legacy_phy_read(dev
, 0x0035);
1564 b43legacy_phy_write(dev
, 0x0035,
1565 (b43legacy_phy_read(dev
, 0x0035) & 0xFF7F));
1566 backup
[11] = b43legacy_read16(dev
, 0x03E6);
1567 backup
[12] = b43legacy_read16(dev
, B43legacy_MMIO_CHANNEL_EXT
);
1569 /* Initialization */
1570 if (phy
->analog
== 0)
1571 b43legacy_write16(dev
, 0x03E6, 0x0122);
1573 if (phy
->analog
>= 2)
1574 b43legacy_phy_write(dev
, 0x0003,
1575 (b43legacy_phy_read(dev
, 0x0003)
1576 & 0xFFBF) | 0x0040);
1577 b43legacy_write16(dev
, B43legacy_MMIO_CHANNEL_EXT
,
1578 (b43legacy_read16(dev
,
1579 B43legacy_MMIO_CHANNEL_EXT
) | 0x2000));
1582 ret
= b43legacy_radio_calibrationvalue(dev
);
1584 if (phy
->type
== B43legacy_PHYTYPE_B
)
1585 b43legacy_radio_write16(dev
, 0x0078, 0x0026);
1588 b43legacy_phy_write(dev
, 0x0812,
1589 b43legacy_get_812_value(dev
,
1591 b43legacy_phy_write(dev
, 0x0015, 0xBFAF);
1592 b43legacy_phy_write(dev
, 0x002B, 0x1403);
1594 b43legacy_phy_write(dev
, 0x0812,
1595 b43legacy_get_812_value(dev
,
1597 b43legacy_phy_write(dev
, 0x0015, 0xBFA0);
1598 b43legacy_radio_write16(dev
, 0x0051,
1599 (b43legacy_radio_read16(dev
, 0x0051)
1601 if (phy
->radio_rev
== 8)
1602 b43legacy_radio_write16(dev
, 0x0043, 0x001F);
1604 b43legacy_radio_write16(dev
, 0x0052, 0x0000);
1605 b43legacy_radio_write16(dev
, 0x0043,
1606 (b43legacy_radio_read16(dev
, 0x0043)
1607 & 0xFFF0) | 0x0009);
1609 b43legacy_phy_write(dev
, 0x0058, 0x0000);
1611 for (i
= 0; i
< 16; i
++) {
1612 b43legacy_phy_write(dev
, 0x005A, 0x0480);
1613 b43legacy_phy_write(dev
, 0x0059, 0xC810);
1614 b43legacy_phy_write(dev
, 0x0058, 0x000D);
1616 b43legacy_phy_write(dev
, 0x0812,
1617 b43legacy_get_812_value(dev
,
1619 b43legacy_phy_write(dev
, 0x0015, 0xAFB0);
1622 b43legacy_phy_write(dev
, 0x0812,
1623 b43legacy_get_812_value(dev
,
1625 b43legacy_phy_write(dev
, 0x0015, 0xEFB0);
1628 b43legacy_phy_write(dev
, 0x0812,
1629 b43legacy_get_812_value(dev
,
1631 b43legacy_phy_write(dev
, 0x0015, 0xFFF0);
1633 tmp1
+= b43legacy_phy_read(dev
, 0x002D);
1634 b43legacy_phy_write(dev
, 0x0058, 0x0000);
1636 b43legacy_phy_write(dev
, 0x0812,
1637 b43legacy_get_812_value(dev
,
1639 b43legacy_phy_write(dev
, 0x0015, 0xAFB0);
1645 b43legacy_phy_write(dev
, 0x0058, 0x0000);
1647 for (i
= 0; i
< 16; i
++) {
1648 b43legacy_radio_write16(dev
, 0x0078, (flip_4bit(i
) << 1)
1650 backup
[13] = b43legacy_radio_read16(dev
, 0x0078);
1652 for (j
= 0; j
< 16; j
++) {
1653 b43legacy_phy_write(dev
, 0x005A, 0x0D80);
1654 b43legacy_phy_write(dev
, 0x0059, 0xC810);
1655 b43legacy_phy_write(dev
, 0x0058, 0x000D);
1657 b43legacy_phy_write(dev
, 0x0812,
1658 b43legacy_get_812_value(dev
,
1660 b43legacy_phy_write(dev
, 0x0015, 0xAFB0);
1663 b43legacy_phy_write(dev
, 0x0812,
1664 b43legacy_get_812_value(dev
,
1666 b43legacy_phy_write(dev
, 0x0015, 0xEFB0);
1669 b43legacy_phy_write(dev
, 0x0812,
1670 b43legacy_get_812_value(dev
,
1672 b43legacy_phy_write(dev
, 0x0015, 0xFFF0);
1674 tmp2
+= b43legacy_phy_read(dev
, 0x002D);
1675 b43legacy_phy_write(dev
, 0x0058, 0x0000);
1677 b43legacy_phy_write(dev
, 0x0812,
1678 b43legacy_get_812_value(dev
,
1680 b43legacy_phy_write(dev
, 0x0015, 0xAFB0);
1688 /* Restore the registers */
1689 b43legacy_phy_write(dev
, 0x0015, backup
[1]);
1690 b43legacy_radio_write16(dev
, 0x0051, backup
[14]);
1691 b43legacy_radio_write16(dev
, 0x0052, backup
[15]);
1692 b43legacy_radio_write16(dev
, 0x0043, backup
[0]);
1693 b43legacy_phy_write(dev
, 0x005A, backup
[16]);
1694 b43legacy_phy_write(dev
, 0x0059, backup
[17]);
1695 b43legacy_phy_write(dev
, 0x0058, backup
[18]);
1696 b43legacy_write16(dev
, 0x03E6, backup
[11]);
1697 if (phy
->analog
!= 0)
1698 b43legacy_write16(dev
, B43legacy_MMIO_CHANNEL_EXT
, backup
[12]);
1699 b43legacy_phy_write(dev
, 0x0035, backup
[10]);
1700 b43legacy_radio_selectchannel(dev
, phy
->channel
, 1);
1701 if (phy
->type
== B43legacy_PHYTYPE_B
) {
1702 b43legacy_phy_write(dev
, 0x0030, backup
[2]);
1703 b43legacy_write16(dev
, 0x03EC, backup
[3]);
1706 b43legacy_write16(dev
, B43legacy_MMIO_PHY_RADIO
,
1707 (b43legacy_read16(dev
,
1708 B43legacy_MMIO_PHY_RADIO
) & 0x7FFF));
1709 b43legacy_phy_write(dev
, 0x0811, backup
[4]);
1710 b43legacy_phy_write(dev
, 0x0812, backup
[5]);
1711 b43legacy_phy_write(dev
, 0x0814, backup
[6]);
1712 b43legacy_phy_write(dev
, 0x0815, backup
[7]);
1713 b43legacy_phy_write(dev
, B43legacy_PHY_G_CRS
,
1715 b43legacy_phy_write(dev
, 0x0802, backup
[9]);
1717 b43legacy_phy_write(dev
, 0x080F, backup
[19]);
1718 b43legacy_phy_write(dev
, 0x0810, backup
[20]);
1729 u16
freq_r3A_value(u16 frequency
)
1733 if (frequency
< 5091)
1735 else if (frequency
< 5321)
1737 else if (frequency
< 5806)
1745 void b43legacy_radio_set_tx_iq(struct b43legacy_wldev
*dev
)
1747 static const u8 data_high
[5] = { 0x00, 0x40, 0x80, 0x90, 0xD0 };
1748 static const u8 data_low
[5] = { 0x00, 0x01, 0x05, 0x06, 0x0A };
1749 u16 tmp
= b43legacy_radio_read16(dev
, 0x001E);
1753 for (i
= 0; i
< 5; i
++) {
1754 for (j
= 0; j
< 5; j
++) {
1755 if (tmp
== (data_high
[i
] | data_low
[j
])) {
1756 b43legacy_phy_write(dev
, 0x0069, (i
- j
) << 8 |
1764 int b43legacy_radio_selectchannel(struct b43legacy_wldev
*dev
,
1766 int synthetic_pu_workaround
)
1768 struct b43legacy_phy
*phy
= &dev
->phy
;
1770 if (channel
== 0xFF) {
1771 switch (phy
->type
) {
1772 case B43legacy_PHYTYPE_B
:
1773 case B43legacy_PHYTYPE_G
:
1774 channel
= B43legacy_RADIO_DEFAULT_CHANNEL_BG
;
1777 B43legacy_WARN_ON(1);
1781 /* TODO: Check if channel is valid - return -EINVAL if not */
1782 if (synthetic_pu_workaround
)
1783 b43legacy_synth_pu_workaround(dev
, channel
);
1785 b43legacy_write16(dev
, B43legacy_MMIO_CHANNEL
,
1786 channel2freq_bg(channel
));
1788 if (channel
== 14) {
1789 if (dev
->dev
->bus
->sprom
.r1
.country_code
== 5) /* JAPAN) */
1790 b43legacy_shm_write32(dev
, B43legacy_SHM_SHARED
,
1791 B43legacy_UCODEFLAGS_OFFSET
,
1792 b43legacy_shm_read32(dev
,
1793 B43legacy_SHM_SHARED
,
1794 B43legacy_UCODEFLAGS_OFFSET
)
1797 b43legacy_shm_write32(dev
, B43legacy_SHM_SHARED
,
1798 B43legacy_UCODEFLAGS_OFFSET
,
1799 b43legacy_shm_read32(dev
,
1800 B43legacy_SHM_SHARED
,
1801 B43legacy_UCODEFLAGS_OFFSET
)
1803 b43legacy_write16(dev
, B43legacy_MMIO_CHANNEL_EXT
,
1804 b43legacy_read16(dev
,
1805 B43legacy_MMIO_CHANNEL_EXT
) | (1 << 11));
1807 b43legacy_write16(dev
, B43legacy_MMIO_CHANNEL_EXT
,
1808 b43legacy_read16(dev
,
1809 B43legacy_MMIO_CHANNEL_EXT
) & 0xF7BF);
1811 phy
->channel
= channel
;
1812 /*XXX: Using the longer of 2 timeouts (8000 vs 2000 usecs). Specs states
1813 * that 2000 usecs might suffice. */
1819 void b43legacy_radio_set_txantenna(struct b43legacy_wldev
*dev
, u32 val
)
1824 tmp
= b43legacy_shm_read16(dev
, B43legacy_SHM_SHARED
, 0x0022) & 0xFCFF;
1825 b43legacy_shm_write16(dev
, B43legacy_SHM_SHARED
, 0x0022, tmp
| val
);
1826 tmp
= b43legacy_shm_read16(dev
, B43legacy_SHM_SHARED
, 0x03A8) & 0xFCFF;
1827 b43legacy_shm_write16(dev
, B43legacy_SHM_SHARED
, 0x03A8, tmp
| val
);
1828 tmp
= b43legacy_shm_read16(dev
, B43legacy_SHM_SHARED
, 0x0054) & 0xFCFF;
1829 b43legacy_shm_write16(dev
, B43legacy_SHM_SHARED
, 0x0054, tmp
| val
);
1832 /* http://bcm-specs.sipsolutions.net/TX_Gain_Base_Band */
1833 static u16
b43legacy_get_txgain_base_band(u16 txpower
)
1837 B43legacy_WARN_ON(txpower
> 63);
1841 else if (txpower
>= 49)
1843 else if (txpower
>= 44)
1851 /* http://bcm-specs.sipsolutions.net/TX_Gain_Radio_Frequency_Power_Amplifier */
1852 static u16
b43legacy_get_txgain_freq_power_amp(u16 txpower
)
1856 B43legacy_WARN_ON(txpower
> 63);
1860 else if (txpower
>= 25)
1862 else if (txpower
>= 20)
1864 else if (txpower
>= 12)
1872 /* http://bcm-specs.sipsolutions.net/TX_Gain_Digital_Analog_Converter */
1873 static u16
b43legacy_get_txgain_dac(u16 txpower
)
1877 B43legacy_WARN_ON(txpower
> 63);
1881 else if (txpower
>= 49)
1883 else if (txpower
>= 44)
1885 else if (txpower
>= 32)
1887 else if (txpower
>= 25)
1889 else if (txpower
>= 20)
1891 else if (txpower
>= 12)
1899 void b43legacy_radio_set_txpower_a(struct b43legacy_wldev
*dev
, u16 txpower
)
1901 struct b43legacy_phy
*phy
= &dev
->phy
;
1907 txpower
= limit_value(txpower
, 0, 63);
1909 pamp
= b43legacy_get_txgain_freq_power_amp(txpower
);
1912 b43legacy_phy_write(dev
, 0x0019, pamp
);
1914 base
= b43legacy_get_txgain_base_band(txpower
);
1916 b43legacy_phy_write(dev
, 0x0017, base
| 0x0020);
1918 ilt
= b43legacy_ilt_read(dev
, 0x3001);
1921 dac
= b43legacy_get_txgain_dac(txpower
);
1925 b43legacy_ilt_write(dev
, 0x3001, dac
);
1927 phy
->txpwr_offset
= txpower
;
1929 /* TODO: FuncPlaceholder (Adjust BB loft cancel) */
1932 void b43legacy_radio_set_txpower_bg(struct b43legacy_wldev
*dev
,
1933 u16 baseband_attenuation
,
1934 u16 radio_attenuation
,
1937 struct b43legacy_phy
*phy
= &dev
->phy
;
1939 if (baseband_attenuation
== 0xFFFF)
1940 baseband_attenuation
= phy
->bbatt
;
1941 if (radio_attenuation
== 0xFFFF)
1942 radio_attenuation
= phy
->rfatt
;
1943 if (txpower
== 0xFFFF)
1944 txpower
= phy
->txctl1
;
1945 phy
->bbatt
= baseband_attenuation
;
1946 phy
->rfatt
= radio_attenuation
;
1947 phy
->txctl1
= txpower
;
1949 B43legacy_WARN_ON(baseband_attenuation
> 11);
1950 if (phy
->radio_rev
< 6)
1951 B43legacy_WARN_ON(radio_attenuation
> 9);
1953 B43legacy_WARN_ON(radio_attenuation
> 31);
1954 B43legacy_WARN_ON(txpower
> 7);
1956 b43legacy_phy_set_baseband_attenuation(dev
, baseband_attenuation
);
1957 b43legacy_radio_write16(dev
, 0x0043, radio_attenuation
);
1958 b43legacy_shm_write16(dev
, B43legacy_SHM_SHARED
, 0x0064,
1960 if (phy
->radio_ver
== 0x2050)
1961 b43legacy_radio_write16(dev
, 0x0052,
1962 (b43legacy_radio_read16(dev
, 0x0052)
1963 & ~0x0070) | ((txpower
<< 4) & 0x0070));
1964 /* FIXME: The spec is very weird and unclear here. */
1965 if (phy
->type
== B43legacy_PHYTYPE_G
)
1966 b43legacy_phy_lo_adjust(dev
, 0);
1969 u16
b43legacy_default_baseband_attenuation(struct b43legacy_wldev
*dev
)
1971 struct b43legacy_phy
*phy
= &dev
->phy
;
1973 if (phy
->radio_ver
== 0x2050 && phy
->radio_rev
< 6)
1978 u16
b43legacy_default_radio_attenuation(struct b43legacy_wldev
*dev
)
1980 struct b43legacy_phy
*phy
= &dev
->phy
;
1983 switch (phy
->radio_ver
) {
1985 switch (phy
->radio_rev
) {
1992 switch (phy
->radio_rev
) {
1997 if (phy
->type
== B43legacy_PHYTYPE_G
) {
1998 if (is_bcm_board_vendor(dev
) &&
1999 dev
->dev
->bus
->boardinfo
.type
== 0x421 &&
2000 dev
->dev
->bus
->boardinfo
.rev
>= 30)
2002 else if (is_bcm_board_vendor(dev
) &&
2003 dev
->dev
->bus
->boardinfo
.type
== 0x416)
2008 if (is_bcm_board_vendor(dev
) &&
2009 dev
->dev
->bus
->boardinfo
.type
== 0x421 &&
2010 dev
->dev
->bus
->boardinfo
.rev
>= 30)
2017 if (phy
->type
== B43legacy_PHYTYPE_G
) {
2018 if (is_bcm_board_vendor(dev
) &&
2019 dev
->dev
->bus
->boardinfo
.type
== 0x421 &&
2020 dev
->dev
->bus
->boardinfo
.rev
>= 30)
2022 else if (is_bcm_board_vendor(dev
) &&
2023 dev
->dev
->bus
->boardinfo
.type
==
2026 else if (dev
->dev
->bus
->chip_id
== 0x4320)
2052 if (is_bcm_board_vendor(dev
) &&
2053 dev
->dev
->bus
->boardinfo
.type
== 0x421) {
2054 if (dev
->dev
->bus
->boardinfo
.rev
< 0x43)
2056 else if (dev
->dev
->bus
->boardinfo
.rev
< 0x51)
2065 u16
b43legacy_default_txctl1(struct b43legacy_wldev
*dev
)
2067 struct b43legacy_phy
*phy
= &dev
->phy
;
2069 if (phy
->radio_ver
!= 0x2050)
2071 if (phy
->radio_rev
== 1)
2073 if (phy
->radio_rev
< 6)
2075 if (phy
->radio_rev
== 8)
2080 void b43legacy_radio_turn_on(struct b43legacy_wldev
*dev
)
2082 struct b43legacy_phy
*phy
= &dev
->phy
;
2091 switch (phy
->type
) {
2092 case B43legacy_PHYTYPE_B
:
2093 case B43legacy_PHYTYPE_G
:
2094 b43legacy_phy_write(dev
, 0x0015, 0x8000);
2095 b43legacy_phy_write(dev
, 0x0015, 0xCC00);
2096 b43legacy_phy_write(dev
, 0x0015,
2097 (phy
->gmode
? 0x00C0 : 0x0000));
2098 if (phy
->radio_off_context
.valid
) {
2099 /* Restore the RFover values. */
2100 b43legacy_phy_write(dev
, B43legacy_PHY_RFOVER
,
2101 phy
->radio_off_context
.rfover
);
2102 b43legacy_phy_write(dev
, B43legacy_PHY_RFOVERVAL
,
2103 phy
->radio_off_context
.rfoverval
);
2104 phy
->radio_off_context
.valid
= 0;
2106 channel
= phy
->channel
;
2107 err
= b43legacy_radio_selectchannel(dev
,
2108 B43legacy_RADIO_DEFAULT_CHANNEL_BG
, 1);
2109 err
|= b43legacy_radio_selectchannel(dev
, channel
, 0);
2110 B43legacy_WARN_ON(err
);
2113 B43legacy_BUG_ON(1);
2116 b43legacy_leds_update(dev
, 0);
2119 void b43legacy_radio_turn_off(struct b43legacy_wldev
*dev
)
2121 struct b43legacy_phy
*phy
= &dev
->phy
;
2123 if (phy
->type
== B43legacy_PHYTYPE_G
&& dev
->dev
->id
.revision
>= 5) {
2124 u16 rfover
, rfoverval
;
2126 rfover
= b43legacy_phy_read(dev
, B43legacy_PHY_RFOVER
);
2127 rfoverval
= b43legacy_phy_read(dev
, B43legacy_PHY_RFOVERVAL
);
2128 phy
->radio_off_context
.rfover
= rfover
;
2129 phy
->radio_off_context
.rfoverval
= rfoverval
;
2130 phy
->radio_off_context
.valid
= 1;
2131 b43legacy_phy_write(dev
, B43legacy_PHY_RFOVER
, rfover
| 0x008C);
2132 b43legacy_phy_write(dev
, B43legacy_PHY_RFOVERVAL
,
2133 rfoverval
& 0xFF73);
2135 b43legacy_phy_write(dev
, 0x0015, 0xAA00);
2137 b43legacydbg(dev
->wl
, "Radio initialized\n");
2138 b43legacy_leds_update(dev
, 0);
2141 void b43legacy_radio_clear_tssi(struct b43legacy_wldev
*dev
)
2143 struct b43legacy_phy
*phy
= &dev
->phy
;
2145 switch (phy
->type
) {
2146 case B43legacy_PHYTYPE_B
:
2147 case B43legacy_PHYTYPE_G
:
2148 b43legacy_shm_write16(dev
, B43legacy_SHM_SHARED
, 0x0058,
2150 b43legacy_shm_write16(dev
, B43legacy_SHM_SHARED
, 0x005a,
2152 b43legacy_shm_write16(dev
, B43legacy_SHM_SHARED
, 0x0070,
2154 b43legacy_shm_write16(dev
, B43legacy_SHM_SHARED
, 0x0072,