aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/phy_n.c
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2011-12-11 07:16:51 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-12-13 15:33:59 -0500
commit49d55cef5b1925a5c1efb6aaddaa40fc7c693335 (patch)
treec14c6110b49e71b76c41204468d798d9b97c6b7e /drivers/net/wireless/b43/phy_n.c
parent38646ebae710da024bdf6e9dcac733bfdb6dd3e1 (diff)
b43: N-PHY: implement spurious tone avoidance
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/phy_n.c')
-rw-r--r--drivers/net/wireless/b43/phy_n.c93
1 files changed, 91 insertions, 2 deletions
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 114c413db482..730f5a451de3 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -4023,6 +4023,61 @@ int b43_phy_initn(struct b43_wldev *dev)
4023 return 0; 4023 return 0;
4024} 4024}
4025 4025
4026/* http://bcm-v4.sipsolutions.net/802.11/PmuSpurAvoid */
4027static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid)
4028{
4029 struct bcma_drv_cc *cc = &dev->dev->bdev->bus->drv_cc;
4030 u32 pmu_ctl;
4031 if (dev->dev->chip_id == 43224 || dev->dev->chip_id == 43225) {
4032 if (avoid) {
4033 bcma_chipco_pll_write(cc, 0x0, 0x11500010);
4034 bcma_chipco_pll_write(cc, 0x1, 0x000C0C06);
4035 bcma_chipco_pll_write(cc, 0x2, 0x0F600a08);
4036 bcma_chipco_pll_write(cc, 0x3, 0x00000000);
4037 bcma_chipco_pll_write(cc, 0x4, 0x2001E920);
4038 bcma_chipco_pll_write(cc, 0x5, 0x88888815);
4039 } else {
4040 bcma_chipco_pll_write(cc, 0x0, 0x11100010);
4041 bcma_chipco_pll_write(cc, 0x1, 0x000c0c06);
4042 bcma_chipco_pll_write(cc, 0x2, 0x03000a08);
4043 bcma_chipco_pll_write(cc, 0x3, 0x00000000);
4044 bcma_chipco_pll_write(cc, 0x4, 0x200005c0);
4045 bcma_chipco_pll_write(cc, 0x5, 0x88888815);
4046 }
4047 pmu_ctl = BCMA_CC_PMU_CTL_PLL_UPD;
4048 } else if (dev->dev->chip_id == 0x4716) {
4049 if (avoid) {
4050 bcma_chipco_pll_write(cc, 0x0, 0x11500060);
4051 bcma_chipco_pll_write(cc, 0x1, 0x080C0C06);
4052 bcma_chipco_pll_write(cc, 0x2, 0x0F600000);
4053 bcma_chipco_pll_write(cc, 0x3, 0x00000000);
4054 bcma_chipco_pll_write(cc, 0x4, 0x2001E924);
4055 bcma_chipco_pll_write(cc, 0x5, 0x88888815);
4056 } else {
4057 bcma_chipco_pll_write(cc, 0x0, 0x11100060);
4058 bcma_chipco_pll_write(cc, 0x1, 0x080c0c06);
4059 bcma_chipco_pll_write(cc, 0x2, 0x03000000);
4060 bcma_chipco_pll_write(cc, 0x3, 0x00000000);
4061 bcma_chipco_pll_write(cc, 0x4, 0x200005c0);
4062 bcma_chipco_pll_write(cc, 0x5, 0x88888815);
4063 }
4064 pmu_ctl = BCMA_CC_PMU_CTL_PLL_UPD | BCMA_CC_PMU_CTL_NOILPONW;
4065 } else if (dev->dev->chip_id == 0x4322 || dev->dev->chip_id == 0x4340 ||
4066 dev->dev->chip_id == 0x4341) {
4067 bcma_chipco_pll_write(cc, 0x0, 0x11100070);
4068 bcma_chipco_pll_write(cc, 0x1, 0x1014140a);
4069 bcma_chipco_pll_write(cc, 0x5, 0x88888854);
4070 if (avoid)
4071 bcma_chipco_pll_write(cc, 0x2, 0x05201828);
4072 else
4073 bcma_chipco_pll_write(cc, 0x2, 0x05001828);
4074 pmu_ctl = BCMA_CC_PMU_CTL_PLL_UPD;
4075 } else {
4076 return;
4077 }
4078 bcma_cc_set32(cc, BCMA_CC_PMU_CTL, pmu_ctl);
4079}
4080
4026/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */ 4081/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ChanspecSetup */
4027static void b43_nphy_channel_setup(struct b43_wldev *dev, 4082static void b43_nphy_channel_setup(struct b43_wldev *dev,
4028 const struct b43_phy_n_sfo_cfg *e, 4083 const struct b43_phy_n_sfo_cfg *e,
@@ -4030,6 +4085,7 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev,
4030{ 4085{
4031 struct b43_phy *phy = &dev->phy; 4086 struct b43_phy *phy = &dev->phy;
4032 struct b43_phy_n *nphy = dev->phy.n; 4087 struct b43_phy_n *nphy = dev->phy.n;
4088 int ch = new_channel->hw_value;
4033 4089
4034 u16 old_band_5ghz; 4090 u16 old_band_5ghz;
4035 u32 tmp32; 4091 u32 tmp32;
@@ -4069,8 +4125,41 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev,
4069 4125
4070 b43_nphy_tx_lp_fbw(dev); 4126 b43_nphy_tx_lp_fbw(dev);
4071 4127
4072 if (dev->phy.rev >= 3 && 0) { 4128 if (dev->phy.rev >= 3 &&
4073 /* TODO */ 4129 dev->phy.n->spur_avoid != B43_SPUR_AVOID_DISABLE) {
4130 bool avoid = false;
4131 if (dev->phy.n->spur_avoid == B43_SPUR_AVOID_FORCE) {
4132 avoid = true;
4133 } else if (!b43_channel_type_is_40mhz(phy->channel_type)) {
4134 if ((ch >= 5 && ch <= 8) || ch == 13 || ch == 14)
4135 avoid = true;
4136 } else { /* 40MHz */
4137 if (nphy->aband_spurwar_en &&
4138 (ch == 38 || ch == 102 || ch == 118))
4139 avoid = dev->dev->chip_id == 0x4716;
4140 }
4141
4142 b43_nphy_pmu_spur_avoid(dev, avoid);
4143
4144 if (dev->dev->chip_id == 43222 || dev->dev->chip_id == 43224 ||
4145 dev->dev->chip_id == 43225) {
4146 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW,
4147 avoid ? 0x5341 : 0x8889);
4148 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
4149 }
4150
4151 if (dev->phy.rev == 3 || dev->phy.rev == 4)
4152 ; /* TODO: reset PLL */
4153
4154 if (avoid)
4155 b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTRX);
4156 else
4157 b43_phy_mask(dev, B43_NPHY_BBCFG,
4158 ~B43_NPHY_BBCFG_RSTRX & 0xFFFF);
4159
4160 b43_nphy_reset_cca(dev);
4161
4162 /* wl sets useless phy_isspuravoid here */
4074 } 4163 }
4075 4164
4076 b43_phy_write(dev, B43_NPHY_NDATAT_DUP40, 0x3830); 4165 b43_phy_write(dev, B43_NPHY_NDATAT_DUP40, 0x3830);