2013-03-28 16:18:12

by Rafał Miłecki

[permalink] [raw]
Subject: [FIX 3.3+][PATCH] ssb: implement spurious tone avoidance

And make use of it in b43. This fixes a regression introduced with
49d55cef5b1925a5c1efb6aaddaa40fc7c693335
b43: N-PHY: implement spurious tone avoidance
This commit made BCM4322 use only MCS 0 on channel 13, which of course
resulted in performance drop (down to 0.7Mb/s).

Reported-by: Stefan Brüns <[email protected]>
Signed-off-by: Rafał Miłecki <[email protected]>
Cc: Stable <[email protected]>
---
John:
While this is fix, unfortunately it's not a one-liner. I wish to see it
in 3.9 and backported to stable kernels, but if you think it's too big,
well, just take it for the next.
---
drivers/net/wireless/b43/phy_n.c | 3 ++-
drivers/ssb/driver_chipcommon_pmu.c | 25 +++++++++++++++++++++++++
include/linux/ssb/ssb_driver_chipcommon.h | 2 ++
3 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index e8486c1..b70f220 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -5165,7 +5165,8 @@ static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid)
#endif
#ifdef CONFIG_B43_SSB
case B43_BUS_SSB:
- /* FIXME */
+ ssb_pmu_spuravoid_pllupdate(&dev->dev->sdev->bus->chipco,
+ avoid);
break;
#endif
}
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c
index 791da2c..8af4c20 100644
--- a/drivers/ssb/driver_chipcommon_pmu.c
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -670,3 +670,28 @@ u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc)
return 0;
}
}
+
+void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid)
+{
+ u32 pmu_ctl = 0;
+
+ switch (cc->dev->bus->chip_id) {
+ case 0x4322:
+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11100070);
+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x1014140a);
+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888854);
+ if (spuravoid == 1)
+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05201828);
+ else
+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05001828);
+ pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD;
+ break;
+ default:
+ ssb_err("Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n",
+ cc->dev->bus->chip_id);
+ return;
+ }
+
+ chipco_set32(cc, SSB_CHIPCO_PMU_CTL, pmu_ctl);
+}
+EXPORT_SYMBOL_GPL(ssb_pmu_spuravoid_pllupdate);
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h
index 9e492be..6fcfe99 100644
--- a/include/linux/ssb/ssb_driver_chipcommon.h
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
@@ -219,6 +219,7 @@
#define SSB_CHIPCO_PMU_CTL 0x0600 /* PMU control */
#define SSB_CHIPCO_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
#define SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT 16
+#define SSB_CHIPCO_PMU_CTL_PLL_UPD 0x00000400
#define SSB_CHIPCO_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
#define SSB_CHIPCO_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
#define SSB_CHIPCO_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
@@ -667,5 +668,6 @@ enum ssb_pmu_ldo_volt_id {
void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
enum ssb_pmu_ldo_volt_id id, u32 voltage);
void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on);
+void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid);

#endif /* LINUX_SSB_CHIPCO_H_ */
--
1.7.10.4



2013-04-01 21:36:53

by Hauke Mehrtens

[permalink] [raw]
Subject: Re: [FIX 3.3+][PATCH] ssb: implement spurious tone avoidance

On 04/01/2013 10:01 PM, John W. Linville wrote:
> On Thu, Mar 28, 2013 at 05:18:02PM +0100, Rafał Miłecki wrote:
>> And make use of it in b43. This fixes a regression introduced with
>> 49d55cef5b1925a5c1efb6aaddaa40fc7c693335
>> b43: N-PHY: implement spurious tone avoidance
>> This commit made BCM4322 use only MCS 0 on channel 13, which of course
>> resulted in performance drop (down to 0.7Mb/s).
>>
>> Reported-by: Stefan Brüns <[email protected]>
>> Signed-off-by: Rafał Miłecki <[email protected]>
>> Cc: Stable <[email protected]>
>> ---
>> John:
>> While this is fix, unfortunately it's not a one-liner. I wish to see it
>> in 3.9 and backported to stable kernels, but if you think it's too big,
>> well, just take it for the next.
>
> CC drivers/ssb/driver_chipcommon_pmu.o
> drivers/ssb/driver_chipcommon_pmu.c: In function ‘ssb_pmu_spuravoid_pllupdate’:
> drivers/ssb/driver_chipcommon_pmu.c:695:3: error: implicit declaration of function ‘ssb_err’ [-Werror=implicit-function-declaration]
> cc1: some warnings being treated as errors
> make[1]: *** [drivers/ssb/driver_chipcommon_pmu.o] Error 1
> make: *** [drivers/ssb/] Error 2
>
> When building in wireless.git...

ssb_err is only in wireless-next, it was added in this commit:
commit 33a606ac8020b47292bcfda30c7888c1ab5233e2
Author: Joe Perches <[email protected]>
Date: Wed Feb 20 12:16:13 2013 -0800

ssb: Convert ssb_printk to ssb_<level>

This version should go into wireless-next for kernel 3.10 and an other
version using ssb_printk(KERN_ERR PFX " instated should go into 3.9 and
stable.

Hauke

2013-04-02 13:57:36

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH V2] ssb: implement spurious tone avoidance

And make use of it in b43. This fixes a regression introduced with
49d55cef5b1925a5c1efb6aaddaa40fc7c693335
b43: N-PHY: implement spurious tone avoidance
This commit made BCM4322 use only MCS 0 on channel 13, which of course
resulted in performance drop (down to 0.7Mb/s).

Reported-by: Stefan Brüns <[email protected]>
Signed-off-by: Rafał Miłecki <[email protected]>
Cc: Stable <[email protected]>
---
V2: use ssb_printk instead of non-existing ssb_err
add BCM43222 case to don't flood dmesg on this chipset

Support for BCM43222 wasn't implemented in this patch, because I don't
own that hardware and I don't dare to send not tested code for "fix" and
stable. I'll implement this in separated patch that will be send for
next tree.

This patch was tested with BCM4322 using wireless git tree (not
wireless-testing!), I've also applied and tested it using kernels 3.4.38
and 3.8.5.
---
drivers/net/wireless/b43/phy_n.c | 3 ++-
drivers/ssb/driver_chipcommon_pmu.c | 29 +++++++++++++++++++++++++++++
include/linux/ssb/ssb_driver_chipcommon.h | 2 ++
3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index e8486c1..b70f220 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -5165,7 +5165,8 @@ static void b43_nphy_pmu_spur_avoid(struct b43_wldev *dev, bool avoid)
#endif
#ifdef CONFIG_B43_SSB
case B43_BUS_SSB:
- /* FIXME */
+ ssb_pmu_spuravoid_pllupdate(&dev->dev->sdev->bus->chipco,
+ avoid);
break;
#endif
}
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c
index 4c0f6d8..7b0bce9 100644
--- a/drivers/ssb/driver_chipcommon_pmu.c
+++ b/drivers/ssb/driver_chipcommon_pmu.c
@@ -675,3 +675,32 @@ u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc)
return 0;
}
}
+
+void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid)
+{
+ u32 pmu_ctl = 0;
+
+ switch (cc->dev->bus->chip_id) {
+ case 0x4322:
+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL0, 0x11100070);
+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL1, 0x1014140a);
+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL5, 0x88888854);
+ if (spuravoid == 1)
+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05201828);
+ else
+ ssb_chipco_pll_write(cc, SSB_PMU1_PLLCTL2, 0x05001828);
+ pmu_ctl = SSB_CHIPCO_PMU_CTL_PLL_UPD;
+ break;
+ case 43222:
+ /* TODO: BCM43222 requires updating PLLs too */
+ return;
+ default:
+ ssb_printk(KERN_ERR PFX
+ "Unknown spuravoidance settings for chip 0x%04X, not changing PLL\n",
+ cc->dev->bus->chip_id);
+ return;
+ }
+
+ chipco_set32(cc, SSB_CHIPCO_PMU_CTL, pmu_ctl);
+}
+EXPORT_SYMBOL_GPL(ssb_pmu_spuravoid_pllupdate);
diff --git a/include/linux/ssb/ssb_driver_chipcommon.h b/include/linux/ssb/ssb_driver_chipcommon.h
index 9e492be..6fcfe99 100644
--- a/include/linux/ssb/ssb_driver_chipcommon.h
+++ b/include/linux/ssb/ssb_driver_chipcommon.h
@@ -219,6 +219,7 @@
#define SSB_CHIPCO_PMU_CTL 0x0600 /* PMU control */
#define SSB_CHIPCO_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
#define SSB_CHIPCO_PMU_CTL_ILP_DIV_SHIFT 16
+#define SSB_CHIPCO_PMU_CTL_PLL_UPD 0x00000400
#define SSB_CHIPCO_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
#define SSB_CHIPCO_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
#define SSB_CHIPCO_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
@@ -667,5 +668,6 @@ enum ssb_pmu_ldo_volt_id {
void ssb_pmu_set_ldo_voltage(struct ssb_chipcommon *cc,
enum ssb_pmu_ldo_volt_id id, u32 voltage);
void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on);
+void ssb_pmu_spuravoid_pllupdate(struct ssb_chipcommon *cc, int spuravoid);

#endif /* LINUX_SSB_CHIPCO_H_ */
--
1.7.10.4


2013-04-01 20:16:07

by John W. Linville

[permalink] [raw]
Subject: Re: [FIX 3.3+][PATCH] ssb: implement spurious tone avoidance

On Thu, Mar 28, 2013 at 05:18:02PM +0100, Rafał Miłecki wrote:
> And make use of it in b43. This fixes a regression introduced with
> 49d55cef5b1925a5c1efb6aaddaa40fc7c693335
> b43: N-PHY: implement spurious tone avoidance
> This commit made BCM4322 use only MCS 0 on channel 13, which of course
> resulted in performance drop (down to 0.7Mb/s).
>
> Reported-by: Stefan Brüns <[email protected]>
> Signed-off-by: Rafał Miłecki <[email protected]>
> Cc: Stable <[email protected]>
> ---
> John:
> While this is fix, unfortunately it's not a one-liner. I wish to see it
> in 3.9 and backported to stable kernels, but if you think it's too big,
> well, just take it for the next.

CC drivers/ssb/driver_chipcommon_pmu.o
drivers/ssb/driver_chipcommon_pmu.c: In function ‘ssb_pmu_spuravoid_pllupdate’:
drivers/ssb/driver_chipcommon_pmu.c:695:3: error: implicit declaration of function ‘ssb_err’ [-Werror=implicit-function-declaration]
cc1: some warnings being treated as errors
make[1]: *** [drivers/ssb/driver_chipcommon_pmu.o] Error 1
make: *** [drivers/ssb/] Error 2

When building in wireless.git...

--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2013-04-02 13:56:50

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [FIX 3.3+][PATCH] ssb: implement spurious tone avoidance

2013/4/1 John W. Linville <[email protected]>:
> On Thu, Mar 28, 2013 at 05:18:02PM +0100, Rafał Miłecki wrote:
>> And make use of it in b43. This fixes a regression introduced with
>> 49d55cef5b1925a5c1efb6aaddaa40fc7c693335
>> b43: N-PHY: implement spurious tone avoidance
>> This commit made BCM4322 use only MCS 0 on channel 13, which of course
>> resulted in performance drop (down to 0.7Mb/s).
>>
>> Reported-by: Stefan Brüns <[email protected]>
>> Signed-off-by: Rafał Miłecki <[email protected]>
>> Cc: Stable <[email protected]>
>> ---
>> John:
>> While this is fix, unfortunately it's not a one-liner. I wish to see it
>> in 3.9 and backported to stable kernels, but if you think it's too big,
>> well, just take it for the next.
>
> CC drivers/ssb/driver_chipcommon_pmu.o
> drivers/ssb/driver_chipcommon_pmu.c: In function ‘ssb_pmu_spuravoid_pllupdate’:
> drivers/ssb/driver_chipcommon_pmu.c:695:3: error: implicit declaration of function ‘ssb_err’ [-Werror=implicit-function-declaration]
> cc1: some warnings being treated as errors
> make[1]: *** [drivers/ssb/driver_chipcommon_pmu.o] Error 1
> make: *** [drivers/ssb/] Error 2
>
> When building in wireless.git...

I'm sorry for that. Tree wireless.git is based on 3.9-rc1, which
contains nouveau regression and I was too lazy to backport fix and
test it well. I could at least try compiling it :|

--
Rafał