aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2013-03-07 10:47:26 -0500
committerJohn W. Linville <linville@tuxdriver.com>2013-03-13 14:27:52 -0400
commit5949e040604128106db1421ab7a73efcc5351809 (patch)
tree78467c21a6cdbc304e43e3951eca761381b232c3
parent4409a23f6bca71d256e05d03215439d6796d9f4e (diff)
b43: HT-PHY: setup TX power control
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/b43/phy_ht.c109
-rw-r--r--drivers/net/wireless/b43/phy_ht.h25
2 files changed, 134 insertions, 0 deletions
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index ae9cd2978060..5e098b844a60 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -557,6 +557,114 @@ static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
557 557
558 /* TODO */ 558 /* TODO */
559} 559}
560
561static void b43_phy_ht_tx_power_ctl_setup(struct b43_wldev *dev)
562{
563 struct b43_phy_ht *phy_ht = dev->phy.ht;
564 struct ssb_sprom *sprom = dev->dev->bus_sprom;
565
566 u8 *idle = phy_ht->idle_tssi;
567 u8 target[3];
568 s16 a1[3], b0[3], b1[3];
569
570 u16 freq = dev->phy.channel_freq;
571 int i, c;
572
573 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
574 for (c = 0; c < 3; c++) {
575 target[c] = sprom->core_pwr_info[c].maxpwr_2g;
576 a1[c] = sprom->core_pwr_info[c].pa_2g[0];
577 b0[c] = sprom->core_pwr_info[c].pa_2g[1];
578 b1[c] = sprom->core_pwr_info[c].pa_2g[2];
579 }
580 } else if (freq >= 4900 && freq < 5100) {
581 for (c = 0; c < 3; c++) {
582 target[c] = sprom->core_pwr_info[c].maxpwr_5gl;
583 a1[c] = sprom->core_pwr_info[c].pa_5gl[0];
584 b0[c] = sprom->core_pwr_info[c].pa_5gl[1];
585 b1[c] = sprom->core_pwr_info[c].pa_5gl[2];
586 }
587 } else if (freq >= 5100 && freq < 5500) {
588 for (c = 0; c < 3; c++) {
589 target[c] = sprom->core_pwr_info[c].maxpwr_5g;
590 a1[c] = sprom->core_pwr_info[c].pa_5g[0];
591 b0[c] = sprom->core_pwr_info[c].pa_5g[1];
592 b1[c] = sprom->core_pwr_info[c].pa_5g[2];
593 }
594 } else if (freq >= 5500) {
595 for (c = 0; c < 3; c++) {
596 target[c] = sprom->core_pwr_info[c].maxpwr_5gh;
597 a1[c] = sprom->core_pwr_info[c].pa_5gh[0];
598 b0[c] = sprom->core_pwr_info[c].pa_5gh[1];
599 b1[c] = sprom->core_pwr_info[c].pa_5gh[2];
600 }
601 } else {
602 target[0] = target[1] = target[2] = 52;
603 a1[0] = a1[1] = a1[2] = -424;
604 b0[0] = b0[1] = b0[2] = 5612;
605 b1[0] = b1[1] = b1[2] = -1393;
606 }
607
608 b43_phy_set(dev, B43_PHY_HT_TSSIMODE, B43_PHY_HT_TSSIMODE_EN);
609 b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1,
610 ~B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN & 0xFFFF);
611
612 /* TODO: Does it depend on sprom->fem.ghz2.tssipos? */
613 b43_phy_set(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI, 0x4000);
614
615 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1,
616 ~B43_PHY_HT_TXPCTL_CMD_C1_INIT, 0x19);
617 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C2,
618 ~B43_PHY_HT_TXPCTL_CMD_C2_INIT, 0x19);
619 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C3,
620 ~B43_PHY_HT_TXPCTL_CMD_C3_INIT, 0x19);
621
622 b43_phy_set(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI,
623 B43_PHY_HT_TXPCTL_IDLE_TSSI_BINF);
624
625 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI,
626 ~B43_PHY_HT_TXPCTL_IDLE_TSSI_C1,
627 idle[0] << B43_PHY_HT_TXPCTL_IDLE_TSSI_C1_SHIFT);
628 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI,
629 ~B43_PHY_HT_TXPCTL_IDLE_TSSI_C2,
630 idle[1] << B43_PHY_HT_TXPCTL_IDLE_TSSI_C2_SHIFT);
631 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI2,
632 ~B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3,
633 idle[2] << B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3_SHIFT);
634
635 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_N, ~B43_PHY_HT_TXPCTL_N_TSSID,
636 0xf0);
637 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_N, ~B43_PHY_HT_TXPCTL_N_NPTIL2,
638 0x3 << B43_PHY_HT_TXPCTL_N_NPTIL2_SHIFT);
639#if 0
640 /* TODO: what to mask/set? */
641 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1, 0x800, 0)
642 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1, 0x400, 0)
643#endif
644
645 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR,
646 ~B43_PHY_HT_TXPCTL_TARG_PWR_C1,
647 target[0] << B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT);
648 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR,
649 ~B43_PHY_HT_TXPCTL_TARG_PWR_C2 & 0xFFFF,
650 target[1] << B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT);
651 b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR2,
652 ~B43_PHY_HT_TXPCTL_TARG_PWR2_C3,
653 target[2] << B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT);
654
655 for (c = 0; c < 3; c++) {
656 s32 num, den, pwr;
657 u32 regval[64];
658
659 for (i = 0; i < 64; i++) {
660 num = 8 * (16 * b0[c] + b1[c] * i);
661 den = 32768 + a1[c] * i;
662 pwr = max((4 * num + den / 2) / den, -8);
663 regval[i] = pwr;
664 }
665 b43_httab_write_bulk(dev, B43_HTTAB16(26 + c, 0), 64, regval);
666 }
667}
560#endif 668#endif
561 669
562/************************************************** 670/**************************************************
@@ -844,6 +952,7 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
844#if 0 952#if 0
845 b43_phy_ht_tx_power_ctl(dev, false); 953 b43_phy_ht_tx_power_ctl(dev, false);
846 b43_phy_ht_tx_power_ctl_idle_tssi(dev); 954 b43_phy_ht_tx_power_ctl_idle_tssi(dev);
955 b43_phy_ht_tx_power_ctl_setup(dev);
847 /* TODO */ 956 /* TODO */
848 b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl); 957 b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl);
849#endif 958#endif
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index 165c5014b7c8..9b2408efb224 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -23,6 +23,9 @@
23#define B43_PHY_HT_SAMP_WAIT_CNT 0x0C5 /* Sample wait count */ 23#define B43_PHY_HT_SAMP_WAIT_CNT 0x0C5 /* Sample wait count */
24#define B43_PHY_HT_SAMP_DEP_CNT 0x0C6 /* Sample depth count */ 24#define B43_PHY_HT_SAMP_DEP_CNT 0x0C6 /* Sample depth count */
25#define B43_PHY_HT_SAMP_STAT 0x0C7 /* Sample status */ 25#define B43_PHY_HT_SAMP_STAT 0x0C7 /* Sample status */
26#define B43_PHY_HT_TSSIMODE 0x122 /* TSSI mode */
27#define B43_PHY_HT_TSSIMODE_EN 0x0001 /* TSSI enable */
28#define B43_PHY_HT_TSSIMODE_PDEN 0x0002 /* Power det enable */
26#define B43_PHY_HT_BW1 0x1CE 29#define B43_PHY_HT_BW1 0x1CE
27#define B43_PHY_HT_BW2 0x1CF 30#define B43_PHY_HT_BW2 0x1CF
28#define B43_PHY_HT_BW3 0x1D0 31#define B43_PHY_HT_BW3 0x1D0
@@ -34,6 +37,22 @@
34#define B43_PHY_HT_TXPCTL_CMD_C1_COEFF 0x2000 /* Power control coefficients */ 37#define B43_PHY_HT_TXPCTL_CMD_C1_COEFF 0x2000 /* Power control coefficients */
35#define B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN 0x4000 /* Hardware TX power control enable */ 38#define B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN 0x4000 /* Hardware TX power control enable */
36#define B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN 0x8000 /* TX power control enable */ 39#define B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN 0x8000 /* TX power control enable */
40#define B43_PHY_HT_TXPCTL_N 0x1E8 /* TX power control N num */
41#define B43_PHY_HT_TXPCTL_N_TSSID 0x00FF /* N TSSI delay */
42#define B43_PHY_HT_TXPCTL_N_TSSID_SHIFT 0
43#define B43_PHY_HT_TXPCTL_N_NPTIL2 0x0700 /* N PT integer log2 */
44#define B43_PHY_HT_TXPCTL_N_NPTIL2_SHIFT 8
45#define B43_PHY_HT_TXPCTL_IDLE_TSSI 0x1E9 /* TX power control idle TSSI */
46#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C1 0x003F
47#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C1_SHIFT 0
48#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C2 0x3F00
49#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C2_SHIFT 8
50#define B43_PHY_HT_TXPCTL_IDLE_TSSI_BINF 0x8000 /* Raw TSSI offset bin format */
51#define B43_PHY_HT_TXPCTL_TARG_PWR 0x1EA /* TX power control target power */
52#define B43_PHY_HT_TXPCTL_TARG_PWR_C1 0x00FF /* Power 0 */
53#define B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT 0
54#define B43_PHY_HT_TXPCTL_TARG_PWR_C2 0xFF00 /* Power 1 */
55#define B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT 8
37#define B43_PHY_HT_TXPCTL_CMD_C2 0x222 56#define B43_PHY_HT_TXPCTL_CMD_C2 0x222
38#define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F 57#define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F
39#define B43_PHY_HT_RSSI_C1 0x219 58#define B43_PHY_HT_RSSI_C1 0x219
@@ -72,6 +91,12 @@
72 91
73#define B43_PHY_HT_TXPCTL_CMD_C3 B43_PHY_EXTG(0x164) 92#define B43_PHY_HT_TXPCTL_CMD_C3 B43_PHY_EXTG(0x164)
74#define B43_PHY_HT_TXPCTL_CMD_C3_INIT 0x007F 93#define B43_PHY_HT_TXPCTL_CMD_C3_INIT 0x007F
94#define B43_PHY_HT_TXPCTL_IDLE_TSSI2 B43_PHY_EXTG(0x165) /* TX power control idle TSSI */
95#define B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3 0x003F
96#define B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3_SHIFT 0
97#define B43_PHY_HT_TXPCTL_TARG_PWR2 B43_PHY_EXTG(0x166) /* TX power control target power */
98#define B43_PHY_HT_TXPCTL_TARG_PWR2_C3 0x00FF
99#define B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT 0
75 100
76#define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A) 101#define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A)
77 102