33 #include <linux/slab.h>
59 static void b43_phy_switch_macfreq(
struct b43_wldev *
dev,
u8 spurmode)
61 if (dev->
dev->chip_id == 43224 || dev->
dev->chip_id == 43225) {
95 static void b43_radio_2064_channel_setup(
struct b43_wldev *dev)
134 if (dev->
phy.rev == 1) {
142 static void b43_radio_2064_init(
struct b43_wldev *dev)
154 if (dev->
phy.rev == 1) {
198 static void b43_phy_lcn_afe_set_unset(
struct b43_wldev *dev)
214 static u16 b43_phy_lcn_get_pa_gain(
struct b43_wldev *dev)
220 static void b43_phy_lcn_set_dac_gain(
struct b43_wldev *dev,
u16 dac_gain)
225 dac_ctrl = dac_ctrl & 0xc7f;
226 dac_ctrl = dac_ctrl | (dac_gain << 7);
231 static void b43_phy_lcn_set_bbmult(
struct b43_wldev *dev,
u8 m0)
237 static void b43_phy_lcn_clear_tx_power_offsets(
struct b43_wldev *dev)
243 for (i = 0; i < 30; i++) {
250 for (i = 0; i < 64; i++) {
257 static void b43_phy_lcn_rev0_baseband_init(
struct b43_wldev *dev)
292 static void b43_phy_lcn_bu_tweaks(
struct b43_wldev *dev)
310 if (dev->
dev->bus_sprom->board_rev >= 0x1204)
318 if (dev->
phy.rev == 1) {
336 b43_phy_lcn_clear_tx_power_offsets(dev);
343 static void b43_phy_lcn_sense_setup(
struct b43_wldev *dev,
346 u8 auxpga_vmidcourse, auxpga_vmidfine, auxpga_gain;
351 u16 save_radio_regs[6][2] = {
352 { 0x007, 0 }, { 0x0ff, 0 }, { 0x11f, 0 }, { 0x005, 0 },
353 { 0x025, 0 }, { 0x112, 0 },
355 u16 save_phy_regs[14][2] = {
356 { 0x503, 0 }, { 0x4a4, 0 }, { 0x4d0, 0 }, { 0x4d9, 0 },
357 { 0x4da, 0 }, { 0x4a6, 0 }, { 0x938, 0 }, { 0x939, 0 },
358 { 0x4d8, 0 }, { 0x4d0, 0 }, { 0x4d7, 0 }, { 0x4a5, 0 },
359 { 0x40d, 0 }, { 0x4a2, 0 },
366 for (i = 0; i < 6; i++)
368 save_radio_regs[i][0]);
369 for (i = 0; i < 14; i++)
370 save_phy_regs[i][1] =
b43_phy_read(dev, save_phy_regs[i][0]);
374 tx_pwr_idx = dev->
phy.lcn->tx_pwr_curr_idx;
410 switch (sense_type) {
414 auxpga_vmidcourse = 8;
415 auxpga_vmidfine = 0x4;
422 auxpga_vmidcourse = 7;
423 auxpga_vmidfine = 0xa;
427 auxpga_vmid = (0x200 | (auxpga_vmidcourse << 4) | auxpga_vmidfine);
442 for (i = 0; i < 6; i++)
444 save_radio_regs[i][1]);
445 for (i = 0; i < 14; i++)
446 b43_phy_write(dev, save_phy_regs[i][0], save_phy_regs[i][1]);
455 static bool b43_phy_lcn_load_tx_iir_cck_filter(
struct b43_wldev *dev,
459 u16 phy_regs[] = { 0x910, 0x91e, 0x91f, 0x924, 0x925, 0x926, 0x920,
460 0x921, 0x927, 0x928, 0x929, 0x922, 0x923, 0x930,
465 { 0, { 1, 415, 1874, 64, 128, 64, 792, 1656, 64, 128, 64, 778,
466 1582, 64, 128, 64 } },
467 { 1, { 1, 402, 1847, 259, 59, 259, 671, 1794, 68, 54, 68, 608,
468 1863, 93, 167, 93 } },
469 { 2, { 1, 415, 1874, 64, 128, 64, 792, 1656, 192, 384, 192,
470 778, 1582, 64, 128, 64 } },
471 { 3, { 1, 302, 1841, 129, 258, 129, 658, 1720, 205, 410, 205,
472 754, 1760, 170, 340, 170 } },
473 { 20, { 1, 360, 1884, 242, 1734, 242, 752, 1720, 205, 1845, 205,
474 767, 1760, 256, 185, 256 } },
475 { 21, { 1, 360, 1884, 149, 1874, 149, 752, 1720, 205, 1883, 205,
476 767, 1760, 256, 273, 256 } },
477 { 22, { 1, 360, 1884, 98, 1948, 98, 752, 1720, 205, 1924, 205,
478 767, 1760, 256, 352, 256 } },
479 { 23, { 1, 350, 1884, 116, 1966, 116, 752, 1720, 205, 2008, 205,
480 767, 1760, 128, 233, 128 } },
481 { 24, { 1, 325, 1884, 32, 40, 32, 756, 1720, 256, 471, 256, 766,
482 1760, 256, 1881, 256 } },
483 { 25, { 1, 299, 1884, 51, 64, 51, 736, 1720, 256, 471, 256, 765,
484 1760, 262, 1878, 262 } },
487 { 26, { 1, 277, 1943, 39, 117, 88, 637, 1838, 64, 192, 144, 614,
488 1864, 128, 384, 288 } },
489 { 27, { 1, 245, 1943, 49, 147, 110, 626, 1838, 256, 768, 576,
490 613, 1864, 128, 384, 288 } },
491 { 30, { 1, 302, 1841, 61, 122, 61, 658, 1720, 205, 410, 205,
492 754, 1760, 170, 340, 170 } },
495 for (i = 0; i <
ARRAY_SIZE(tx_iir_filters_cck); i++) {
496 if (tx_iir_filters_cck[i].
type == filter_type) {
497 for (j = 0; j < 16; j++)
499 tx_iir_filters_cck[i].
values[j]);
507 static bool b43_phy_lcn_load_tx_iir_ofdm_filter(
struct b43_wldev *dev,
511 u16 phy_regs[] = { 0x90f, 0x900, 0x901, 0x906, 0x907, 0x908, 0x902,
512 0x903, 0x909, 0x90a, 0x90b, 0x904, 0x905, 0x90c,
515 { 0, { 0, 0xa2, 0x0, 0x100, 0x100, 0x0, 0x0, 0x0, 0x100, 0x0,
516 0x0, 0x278, 0xfea0, 0x80, 0x100, 0x80 } },
517 { 1, { 0, 374, 0xFF79, 16, 32, 16, 799, 0xFE74, 50, 32, 50, 750,
518 0xFE2B, 212, 0xFFCE, 212 } },
519 { 2, { 0, 375, 0xFF16, 37, 76, 37, 799, 0xFE74, 32, 20, 32, 748,
520 0xFEF2, 128, 0xFFE2, 128 } },
523 for (i = 0; i <
ARRAY_SIZE(tx_iir_filters_ofdm); i++) {
524 if (tx_iir_filters_ofdm[i].
type == filter_type) {
525 for (j = 0; j < 16; j++)
527 tx_iir_filters_ofdm[i].
values[j]);
536 static void b43_phy_lcn_set_tx_gain_override(
struct b43_wldev *dev,
bool enable)
544 static void b43_phy_lcn_set_tx_gain(
struct b43_wldev *dev,
547 u16 pa_gain = b43_phy_lcn_get_pa_gain(dev);
552 (target_gains->
pad_gain | (pa_gain << 8)));
556 (target_gains->
pad_gain | (pa_gain << 8)));
558 b43_phy_lcn_set_dac_gain(dev, target_gains->
dac_gain);
559 b43_phy_lcn_set_tx_gain_override(dev,
true);
563 static void b43_phy_lcn_tx_pwr_ctl_init(
struct b43_wldev *dev)
570 if (!dev->
phy.lcn->hw_pwr_ctl_capable) {
572 tx_gains.gm_gain = 4;
573 tx_gains.pga_gain = 12;
574 tx_gains.pad_gain = 12;
575 tx_gains.dac_gain = 0;
578 tx_gains.gm_gain = 7;
579 tx_gains.pga_gain = 15;
580 tx_gains.pad_gain = 14;
581 tx_gains.dac_gain = 0;
584 b43_phy_lcn_set_tx_gain(dev, &tx_gains);
585 b43_phy_lcn_set_bbmult(dev, bbmult);
588 b43err(dev->
wl,
"TX power control not supported for this HW\n");
595 static void b43_phy_lcn_txrx_spur_avoidance_mode(
struct b43_wldev *dev,
612 b43_phy_switch_macfreq(dev, enable);
620 static void b43_phy_lcn_set_channel_tweaks(
struct b43_wldev *dev,
int channel)
626 if (channel == 1 || channel == 2 || channel == 3 || channel == 4 ||
627 channel == 9 || channel == 10 || channel == 11 || channel == 12) {
636 b43_phy_lcn_txrx_spur_avoidance_mode(dev,
false);
648 b43_phy_lcn_txrx_spur_avoidance_mode(dev,
true);
658 static int b43_phy_lcn_set_channel(
struct b43_wldev *dev,
662 static const u16 sfo_cfg[14][2] = {
663 {965, 1087}, {967, 1085}, {969, 1082}, {971, 1080}, {973, 1078},
664 {975, 1076}, {977, 1073}, {979, 1071}, {981, 1069}, {983, 1067},
665 {985, 1065}, {987, 1063}, {989, 1060}, {994, 1055},
668 b43_phy_lcn_set_channel_tweaks(dev, channel->
hw_value);
673 b43_radio_2064_channel_setup(dev);
676 b43_phy_lcn_afe_set_unset(dev);
683 b43_phy_lcn_load_tx_iir_cck_filter(dev, 3);
687 b43_phy_lcn_load_tx_iir_cck_filter(dev, 25);
690 b43_phy_lcn_load_tx_iir_ofdm_filter(dev, 0);
701 static int b43_phy_lcn_op_allocate(
struct b43_wldev *dev)
705 phy_lcn = kzalloc(
sizeof(*phy_lcn),
GFP_KERNEL);
708 dev->
phy.lcn = phy_lcn;
713 static void b43_phy_lcn_op_free(
struct b43_wldev *dev)
722 static void b43_phy_lcn_op_prepare_structs(
struct b43_wldev *dev)
727 memset(phy_lcn, 0,
sizeof(*phy_lcn));
731 static int b43_phy_lcn_op_init(
struct b43_wldev *dev)
740 b43_phy_lcn_afe_set_unset(dev);
748 b43_phy_lcn_rev0_baseband_init(dev);
749 b43_phy_lcn_bu_tweaks(dev);
751 if (dev->
phy.radio_ver == 0x2064)
752 b43_radio_2064_init(dev);
757 b43_phy_lcn_tx_pwr_ctl_init(dev);
775 static void b43_phy_lcn_op_software_rfkill(
struct b43_wldev *dev,
779 b43err(dev->
wl,
"MAC not suspended\n");
798 static void b43_phy_lcn_op_switch_analog(
struct b43_wldev *dev,
bool on)
808 static int b43_phy_lcn_op_switch_channel(
struct b43_wldev *dev,
809 unsigned int new_channel)
815 if ((new_channel < 1) || (new_channel > 14))
821 return b43_phy_lcn_set_channel(dev, channel, channel_type);
824 static unsigned int b43_phy_lcn_op_get_default_chan(
struct b43_wldev *dev)
832 b43_phy_lcn_op_recalc_txpower(
struct b43_wldev *dev,
bool ignore_tssi)
837 static void b43_phy_lcn_op_adjust_txpower(
struct b43_wldev *dev)
874 static void b43_phy_lcn_op_radio_write(
struct b43_wldev *dev,
u16 reg,
886 .allocate = b43_phy_lcn_op_allocate,
887 .free = b43_phy_lcn_op_free,
888 .prepare_structs = b43_phy_lcn_op_prepare_structs,
889 .init = b43_phy_lcn_op_init,
890 .phy_read = b43_phy_lcn_op_read,
891 .phy_write = b43_phy_lcn_op_write,
892 .phy_maskset = b43_phy_lcn_op_maskset,
893 .radio_read = b43_phy_lcn_op_radio_read,
894 .radio_write = b43_phy_lcn_op_radio_write,
895 .software_rfkill = b43_phy_lcn_op_software_rfkill,
896 .switch_analog = b43_phy_lcn_op_switch_analog,
897 .switch_channel = b43_phy_lcn_op_switch_channel,
898 .get_default_chan = b43_phy_lcn_op_get_default_chan,
899 .recalc_txpower = b43_phy_lcn_op_recalc_txpower,
900 .adjust_txpower = b43_phy_lcn_op_adjust_txpower,