2013-03-07 15:47:33

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 00/13] b43: implement basic TX power mgmt

After spotting a lot of N-PHY-similar functions in
BCM4331 dump of MMIO ops - split into names parts
I was able to finally improve HT-PHY code.

It now sets TX basically, I can finally talk with devices that are few
meters away, not just few centimetres. It's a little patch bomb, sorry
for that, but I wasn't sure if my code is correct until it was complete
and started working.

Rafał Miłecki (13):
b43: HT-PHY: rename AFE defines
b43: HT-PHY: add classifier control function
b43: HT-PHY: move TX fix to the separated function
b43: HT-PHY: implement spurious tone avoidance
b43: HT-PHY: implement MAC reclocking
b43: HT-PHY: implement CCA reset
b43: HT-PHY: implement PA override
b43: HT-PHY: implement controlling TX power control
b43: HT-PHY: implement stopping sample tone playback
b43: HT-PHY: implement playing sample tone
b43: HT-PHY: implement RSSI polling
b43: HT-PHY: setup TX power control
b43: HT-PHY: enable basic TX power setup

drivers/net/wireless/b43/phy_ht.c | 603 +++++++++++++++++++++++++++++++++----
drivers/net/wireless/b43/phy_ht.h | 77 ++++-
2 files changed, 613 insertions(+), 67 deletions(-)

--
1.7.10.4



2013-03-07 16:41:16

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 11/13] b43: HT-PHY: implement RSSI polling

2013/3/7 Michael Büsch <[email protected]>:
> On Thu, 7 Mar 2013 16:47:25 +0100
> Rafał Miłecki <[email protected]> wrote:
>
>> + const u16 ctl_regs[3][2] = {
>> + { B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER, },
>> + { B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER, },
>> + { B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER, },
>> + };
>> + const u16 radio_r[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1, };
>
>> + u16 phy_regs_to_save[] = {
>> + B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER,
>> + 0x848, 0x841,
>> + B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER,
>> + 0x868, 0x861,
>> + B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER,
>> + 0x888, 0x881,
>> + };
>
> It usually is better to define tables that are constant as "static const",
> so that they are not put on the kernel stack.

Thanks, I'll fix that, will just wait a little longer for more
comments (if any appear)

--
Rafał

2013-03-09 12:49:13

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH V2 07/13] b43: HT-PHY: implement PA override

Signed-off-by: Rafał Miłecki <[email protected]>
---
V2: use static for "regs" array
---
drivers/net/wireless/b43/phy_ht.c | 22 ++++++++++++++++++++++
drivers/net/wireless/b43/phy_ht.h | 5 +++++
2 files changed, 27 insertions(+)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 23a46c6..1998dca 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -178,6 +178,26 @@ static void b43_phy_ht_force_rf_sequence(struct b43_wldev *dev, u16 rf_seq)
b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode);
}

+static void b43_phy_ht_pa_override(struct b43_wldev *dev, bool enable)
+{
+ struct b43_phy_ht *htphy = dev->phy.ht;
+ static const u16 regs[3] = { B43_PHY_HT_RF_CTL_INT_C1,
+ B43_PHY_HT_RF_CTL_INT_C2,
+ B43_PHY_HT_RF_CTL_INT_C3 };
+ int i;
+
+ if (enable) {
+ for (i = 0; i < 3; i++)
+ b43_phy_write(dev, regs[i], htphy->rf_ctl_int_save[i]);
+ } else {
+ for (i = 0; i < 3; i++)
+ htphy->rf_ctl_int_save[i] = b43_phy_read(dev, regs[i]);
+ /* TODO: Does 5GHz band use different value (not 0x0400)? */
+ for (i = 0; i < 3; i++)
+ b43_phy_write(dev, regs[i], 0x0400);
+ }
+}
+
/**************************************************
* Various PHY ops
**************************************************/
@@ -554,8 +574,10 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)

b43_mac_phy_clock_set(dev, true);

+ b43_phy_ht_pa_override(dev, false);
b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RX2TX);
b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX);
+ b43_phy_ht_pa_override(dev, true);

/* TODO: Should we restore it? Or store it in global PHY info? */
b43_phy_ht_classifier(dev, 0, 0);
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index 52603af..684807c 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -40,6 +40,10 @@

#define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010)

+#define B43_PHY_HT_RF_CTL_INT_C1 B43_PHY_EXTG(0x04c)
+#define B43_PHY_HT_RF_CTL_INT_C2 B43_PHY_EXTG(0x06c)
+#define B43_PHY_HT_RF_CTL_INT_C3 B43_PHY_EXTG(0x08c)
+
#define B43_PHY_HT_AFE_C1_OVER B43_PHY_EXTG(0x110)
#define B43_PHY_HT_AFE_C1 B43_PHY_EXTG(0x111)
#define B43_PHY_HT_AFE_C2_OVER B43_PHY_EXTG(0x114)
@@ -62,6 +66,7 @@ struct b43_phy_ht_channeltab_e_phy {


struct b43_phy_ht {
+ u16 rf_ctl_int_save[3];
};


--
1.7.10.4


2013-03-07 15:47:41

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 01/13] b43: HT-PHY: rename AFE defines

It you take a look at N-PHY analog switch function it touches every core
on the chipset. It seems HT-PHY does they same, it just has 3 cores
instead of 2 (which make sense since BCM4331 is 3x3). Rename AFE defines
to include core id.

Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_ht.c | 36 ++++++++++++++++++------------------
drivers/net/wireless/b43/phy_ht.h | 12 ++++++------
2 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 3719a88..20c4cb7f 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -177,9 +177,9 @@ static void b43_phy_ht_afe_unk1(struct b43_wldev *dev)
u8 i;

const u16 ctl_regs[3][2] = {
- { B43_PHY_HT_AFE_CTL1, B43_PHY_HT_AFE_CTL2 },
- { B43_PHY_HT_AFE_CTL3, B43_PHY_HT_AFE_CTL4 },
- { B43_PHY_HT_AFE_CTL5, B43_PHY_HT_AFE_CTL6},
+ { B43_PHY_HT_AFE_C1_OVER, B43_PHY_HT_AFE_C1 },
+ { B43_PHY_HT_AFE_C2_OVER, B43_PHY_HT_AFE_C2 },
+ { B43_PHY_HT_AFE_C3_OVER, B43_PHY_HT_AFE_C3},
};

for (i = 0; i < 3; i++) {
@@ -362,9 +362,9 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)

b43_phy_mask(dev, B43_PHY_EXTG(0), ~0x3);

- b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0);

b43_phy_write(dev, B43_PHY_EXTG(0x103), 0x20);
b43_phy_write(dev, B43_PHY_EXTG(0x101), 0x20);
@@ -511,19 +511,19 @@ static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev,
static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on)
{
if (on) {
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00cd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x0000);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00cd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x0000);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00cd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x0000);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1, 0x00cd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0x0000);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2, 0x00cd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0x0000);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3, 0x00cd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0x0000);
} else {
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x07ff);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00fd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x07ff);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00fd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x07ff);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00fd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0x07ff);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1, 0x00fd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0x07ff);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2, 0x00fd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0x07ff);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3, 0x00fd);
}
}

diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index 6544c42..60824fa 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -36,12 +36,12 @@

#define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010)

-#define B43_PHY_HT_AFE_CTL1 B43_PHY_EXTG(0x110)
-#define B43_PHY_HT_AFE_CTL2 B43_PHY_EXTG(0x111)
-#define B43_PHY_HT_AFE_CTL3 B43_PHY_EXTG(0x114)
-#define B43_PHY_HT_AFE_CTL4 B43_PHY_EXTG(0x115)
-#define B43_PHY_HT_AFE_CTL5 B43_PHY_EXTG(0x118)
-#define B43_PHY_HT_AFE_CTL6 B43_PHY_EXTG(0x119)
+#define B43_PHY_HT_AFE_C1_OVER B43_PHY_EXTG(0x110)
+#define B43_PHY_HT_AFE_C1 B43_PHY_EXTG(0x111)
+#define B43_PHY_HT_AFE_C2_OVER B43_PHY_EXTG(0x114)
+#define B43_PHY_HT_AFE_C2 B43_PHY_EXTG(0x115)
+#define B43_PHY_HT_AFE_C3_OVER B43_PHY_EXTG(0x118)
+#define B43_PHY_HT_AFE_C3 B43_PHY_EXTG(0x119)


/* Values for PHY registers used on channel switching */
--
1.7.10.4


2013-03-07 15:47:51

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 05/13] b43: HT-PHY: implement MAC reclocking


Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_ht.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 4ccd371..4b24816 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -290,6 +290,7 @@ static void b43_phy_ht_spur_avoid(struct b43_wldev *dev,
{
struct bcma_device *core = dev->dev->bdev;
int spuravoid = 0;
+ u16 tmp;

/* Check for 13 and 14 is just a guess, we don't have enough logs. */
if (new_channel->hw_value == 13 || new_channel->hw_value == 14)
@@ -301,6 +302,23 @@ static void b43_phy_ht_spur_avoid(struct b43_wldev *dev,
B43_BCMA_CLKCTLST_PHY_PLL_REQ,
B43_BCMA_CLKCTLST_80211_PLL_ST |
B43_BCMA_CLKCTLST_PHY_PLL_ST, false);
+
+ /* Values has been taken from wlc_bmac_switch_macfreq comments */
+ switch (spuravoid) {
+ case 2: /* 126MHz */
+ tmp = 0x2082;
+ break;
+ case 1: /* 123MHz */
+ tmp = 0x5341;
+ break;
+ default: /* 120MHz */
+ tmp = 0x8889;
+ }
+
+ b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, tmp);
+ b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
+
+ /* TODO: reset PLL */
}

static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
--
1.7.10.4


2013-03-07 15:48:09

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 12/13] b43: HT-PHY: setup TX power control


Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_ht.c | 109 +++++++++++++++++++++++++++++++++++++
drivers/net/wireless/b43/phy_ht.h | 25 +++++++++
2 files changed, 134 insertions(+)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 831dca4..6d5eb04 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)

/* TODO */
}
+
+static void b43_phy_ht_tx_power_ctl_setup(struct b43_wldev *dev)
+{
+ struct b43_phy_ht *phy_ht = dev->phy.ht;
+ struct ssb_sprom *sprom = dev->dev->bus_sprom;
+
+ u8 *idle = phy_ht->idle_tssi;
+ u8 target[3];
+ s16 a1[3], b0[3], b1[3];
+
+ u16 freq = dev->phy.channel_freq;
+ int i, c;
+
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
+ for (c = 0; c < 3; c++) {
+ target[c] = sprom->core_pwr_info[c].maxpwr_2g;
+ a1[c] = sprom->core_pwr_info[c].pa_2g[0];
+ b0[c] = sprom->core_pwr_info[c].pa_2g[1];
+ b1[c] = sprom->core_pwr_info[c].pa_2g[2];
+ }
+ } else if (freq >= 4900 && freq < 5100) {
+ for (c = 0; c < 3; c++) {
+ target[c] = sprom->core_pwr_info[c].maxpwr_5gl;
+ a1[c] = sprom->core_pwr_info[c].pa_5gl[0];
+ b0[c] = sprom->core_pwr_info[c].pa_5gl[1];
+ b1[c] = sprom->core_pwr_info[c].pa_5gl[2];
+ }
+ } else if (freq >= 5100 && freq < 5500) {
+ for (c = 0; c < 3; c++) {
+ target[c] = sprom->core_pwr_info[c].maxpwr_5g;
+ a1[c] = sprom->core_pwr_info[c].pa_5g[0];
+ b0[c] = sprom->core_pwr_info[c].pa_5g[1];
+ b1[c] = sprom->core_pwr_info[c].pa_5g[2];
+ }
+ } else if (freq >= 5500) {
+ for (c = 0; c < 3; c++) {
+ target[c] = sprom->core_pwr_info[c].maxpwr_5gh;
+ a1[c] = sprom->core_pwr_info[c].pa_5gh[0];
+ b0[c] = sprom->core_pwr_info[c].pa_5gh[1];
+ b1[c] = sprom->core_pwr_info[c].pa_5gh[2];
+ }
+ } else {
+ target[0] = target[1] = target[2] = 52;
+ a1[0] = a1[1] = a1[2] = -424;
+ b0[0] = b0[1] = b0[2] = 5612;
+ b1[0] = b1[1] = b1[2] = -1393;
+ }
+
+ b43_phy_set(dev, B43_PHY_HT_TSSIMODE, B43_PHY_HT_TSSIMODE_EN);
+ b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1,
+ ~B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN & 0xFFFF);
+
+ /* TODO: Does it depend on sprom->fem.ghz2.tssipos? */
+ b43_phy_set(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI, 0x4000);
+
+ b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1,
+ ~B43_PHY_HT_TXPCTL_CMD_C1_INIT, 0x19);
+ b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C2,
+ ~B43_PHY_HT_TXPCTL_CMD_C2_INIT, 0x19);
+ b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C3,
+ ~B43_PHY_HT_TXPCTL_CMD_C3_INIT, 0x19);
+
+ b43_phy_set(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI,
+ B43_PHY_HT_TXPCTL_IDLE_TSSI_BINF);
+
+ b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI,
+ ~B43_PHY_HT_TXPCTL_IDLE_TSSI_C1,
+ idle[0] << B43_PHY_HT_TXPCTL_IDLE_TSSI_C1_SHIFT);
+ b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI,
+ ~B43_PHY_HT_TXPCTL_IDLE_TSSI_C2,
+ idle[1] << B43_PHY_HT_TXPCTL_IDLE_TSSI_C2_SHIFT);
+ b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_IDLE_TSSI2,
+ ~B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3,
+ idle[2] << B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3_SHIFT);
+
+ b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_N, ~B43_PHY_HT_TXPCTL_N_TSSID,
+ 0xf0);
+ b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_N, ~B43_PHY_HT_TXPCTL_N_NPTIL2,
+ 0x3 << B43_PHY_HT_TXPCTL_N_NPTIL2_SHIFT);
+#if 0
+ /* TODO: what to mask/set? */
+ b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1, 0x800, 0)
+ b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_CMD_C1, 0x400, 0)
+#endif
+
+ b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR,
+ ~B43_PHY_HT_TXPCTL_TARG_PWR_C1,
+ target[0] << B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT);
+ b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR,
+ ~B43_PHY_HT_TXPCTL_TARG_PWR_C2 & 0xFFFF,
+ target[1] << B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT);
+ b43_phy_maskset(dev, B43_PHY_HT_TXPCTL_TARG_PWR2,
+ ~B43_PHY_HT_TXPCTL_TARG_PWR2_C3,
+ target[2] << B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT);
+
+ for (c = 0; c < 3; c++) {
+ s32 num, den, pwr;
+ u32 regval[64];
+
+ for (i = 0; i < 64; i++) {
+ num = 8 * (16 * b0[c] + b1[c] * i);
+ den = 32768 + a1[c] * i;
+ pwr = max((4 * num + den / 2) / den, -8);
+ regval[i] = pwr;
+ }
+ b43_httab_write_bulk(dev, B43_HTTAB16(26 + c, 0), 64, regval);
+ }
+}
#endif

/**************************************************
@@ -844,6 +952,7 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
#if 0
b43_phy_ht_tx_power_ctl(dev, false);
b43_phy_ht_tx_power_ctl_idle_tssi(dev);
+ b43_phy_ht_tx_power_ctl_setup(dev);
/* TODO */
b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl);
#endif
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index 165c501..9b2408e 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -23,6 +23,9 @@
#define B43_PHY_HT_SAMP_WAIT_CNT 0x0C5 /* Sample wait count */
#define B43_PHY_HT_SAMP_DEP_CNT 0x0C6 /* Sample depth count */
#define B43_PHY_HT_SAMP_STAT 0x0C7 /* Sample status */
+#define B43_PHY_HT_TSSIMODE 0x122 /* TSSI mode */
+#define B43_PHY_HT_TSSIMODE_EN 0x0001 /* TSSI enable */
+#define B43_PHY_HT_TSSIMODE_PDEN 0x0002 /* Power det enable */
#define B43_PHY_HT_BW1 0x1CE
#define B43_PHY_HT_BW2 0x1CF
#define B43_PHY_HT_BW3 0x1D0
@@ -34,6 +37,22 @@
#define B43_PHY_HT_TXPCTL_CMD_C1_COEFF 0x2000 /* Power control coefficients */
#define B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN 0x4000 /* Hardware TX power control enable */
#define B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN 0x8000 /* TX power control enable */
+#define B43_PHY_HT_TXPCTL_N 0x1E8 /* TX power control N num */
+#define B43_PHY_HT_TXPCTL_N_TSSID 0x00FF /* N TSSI delay */
+#define B43_PHY_HT_TXPCTL_N_TSSID_SHIFT 0
+#define B43_PHY_HT_TXPCTL_N_NPTIL2 0x0700 /* N PT integer log2 */
+#define B43_PHY_HT_TXPCTL_N_NPTIL2_SHIFT 8
+#define B43_PHY_HT_TXPCTL_IDLE_TSSI 0x1E9 /* TX power control idle TSSI */
+#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C1 0x003F
+#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C1_SHIFT 0
+#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C2 0x3F00
+#define B43_PHY_HT_TXPCTL_IDLE_TSSI_C2_SHIFT 8
+#define B43_PHY_HT_TXPCTL_IDLE_TSSI_BINF 0x8000 /* Raw TSSI offset bin format */
+#define B43_PHY_HT_TXPCTL_TARG_PWR 0x1EA /* TX power control target power */
+#define B43_PHY_HT_TXPCTL_TARG_PWR_C1 0x00FF /* Power 0 */
+#define B43_PHY_HT_TXPCTL_TARG_PWR_C1_SHIFT 0
+#define B43_PHY_HT_TXPCTL_TARG_PWR_C2 0xFF00 /* Power 1 */
+#define B43_PHY_HT_TXPCTL_TARG_PWR_C2_SHIFT 8
#define B43_PHY_HT_TXPCTL_CMD_C2 0x222
#define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F
#define B43_PHY_HT_RSSI_C1 0x219
@@ -72,6 +91,12 @@

#define B43_PHY_HT_TXPCTL_CMD_C3 B43_PHY_EXTG(0x164)
#define B43_PHY_HT_TXPCTL_CMD_C3_INIT 0x007F
+#define B43_PHY_HT_TXPCTL_IDLE_TSSI2 B43_PHY_EXTG(0x165) /* TX power control idle TSSI */
+#define B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3 0x003F
+#define B43_PHY_HT_TXPCTL_IDLE_TSSI2_C3_SHIFT 0
+#define B43_PHY_HT_TXPCTL_TARG_PWR2 B43_PHY_EXTG(0x166) /* TX power control target power */
+#define B43_PHY_HT_TXPCTL_TARG_PWR2_C3 0x00FF
+#define B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT 0

#define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A)

--
1.7.10.4


2013-03-07 15:47:44

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 02/13] b43: HT-PHY: add classifier control function

After comparing operations on reg 0xB on N and HT it seems to be the
same register with similar ops. Implement them for HT-PHY.

Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_ht.c | 36 +++++++++++++++++++++++++++++++-----
drivers/net/wireless/b43/phy_ht.h | 6 ++++++
2 files changed, 37 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 20c4cb7f..2a65d01 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -157,6 +157,22 @@ static void b43_radio_2059_init(struct b43_wldev *dev)
* Various PHY ops
**************************************************/

+static u16 b43_phy_ht_classifier(struct b43_wldev *dev, u16 mask, u16 val)
+{
+ u16 tmp;
+ u16 allowed = B43_PHY_HT_CLASS_CTL_CCK_EN |
+ B43_PHY_HT_CLASS_CTL_OFDM_EN |
+ B43_PHY_HT_CLASS_CTL_WAITED_EN;
+
+ tmp = b43_phy_read(dev, B43_PHY_HT_CLASS_CTL);
+ tmp &= allowed;
+ tmp &= ~mask;
+ tmp |= (val & mask);
+ b43_phy_maskset(dev, B43_PHY_HT_CLASS_CTL, ~allowed, tmp);
+
+ return tmp;
+}
+
static void b43_phy_ht_zero_extg(struct b43_wldev *dev)
{
u8 i, j;
@@ -264,7 +280,15 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
b43_phy_write(dev, B43_PHY_HT_BW5, e->bw5);
b43_phy_write(dev, B43_PHY_HT_BW6, e->bw6);

- /* TODO: some ops on PHY regs 0x0B0 and 0xC0A */
+ if (new_channel->hw_value == 14) {
+ b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_OFDM_EN, 0);
+ b43_phy_set(dev, B43_PHY_HT_TEST, 0x0800);
+ } else {
+ b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_OFDM_EN,
+ B43_PHY_HT_CLASS_CTL_OFDM_EN);
+ if (new_channel->band == IEEE80211_BAND_2GHZ)
+ b43_phy_mask(dev, B43_PHY_HT_TEST, ~0x840);
+ }

/* TODO: separated function? */
for (i = 0; i < 3; i++) {
@@ -376,8 +400,11 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
if (0) /* TODO: condition */
; /* TODO: PHY op on reg 0x217 */

- b43_phy_read(dev, 0xb0); /* TODO: what for? */
- b43_phy_set(dev, 0xb0, 0x1);
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
+ b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_CCK_EN, 0);
+ else
+ b43_phy_ht_classifier(dev, B43_PHY_HT_CLASS_CTL_CCK_EN,
+ B43_PHY_HT_CLASS_CTL_CCK_EN);

b43_phy_set(dev, 0xb1, 0x91);
b43_phy_write(dev, 0x32f, 0x0003);
@@ -456,9 +483,8 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RX2TX);
b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX);

- /* TODO: PHY op on reg 0xb0 */
-
/* TODO: Should we restore it? Or store it in global PHY info? */
+ b43_phy_ht_classifier(dev, 0, 0);
b43_phy_ht_read_clip_detection(dev, clip_state);

if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index 60824fa..52603af 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -12,6 +12,10 @@
#define B43_PHY_HT_TABLE_ADDR 0x072 /* Table address */
#define B43_PHY_HT_TABLE_DATALO 0x073 /* Table data low */
#define B43_PHY_HT_TABLE_DATAHI 0x074 /* Table data high */
+#define B43_PHY_HT_CLASS_CTL 0x0B0 /* Classifier control */
+#define B43_PHY_HT_CLASS_CTL_CCK_EN 0x0001 /* CCK enable */
+#define B43_PHY_HT_CLASS_CTL_OFDM_EN 0x0002 /* OFDM enable */
+#define B43_PHY_HT_CLASS_CTL_WAITED_EN 0x0004 /* Waited enable */
#define B43_PHY_HT_BW1 0x1CE
#define B43_PHY_HT_BW2 0x1CF
#define B43_PHY_HT_BW3 0x1D0
@@ -43,6 +47,8 @@
#define B43_PHY_HT_AFE_C3_OVER B43_PHY_EXTG(0x118)
#define B43_PHY_HT_AFE_C3 B43_PHY_EXTG(0x119)

+#define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A)
+

/* Values for PHY registers used on channel switching */
struct b43_phy_ht_channeltab_e_phy {
--
1.7.10.4


2013-03-07 15:47:59

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 08/13] b43: HT-PHY: implement controlling TX power control

Don't enable it until we have (almost?) whole TX power management
figured out. It's similar to the N-PHY, the difference is that we call a
"fix" *before* disabling power control.

Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_ht.c | 55 +++++++++++++++++++++++++++++++++++++
drivers/net/wireless/b43/phy_ht.h | 13 +++++++++
2 files changed, 68 insertions(+)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 3b3517c..4300867 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -319,6 +319,46 @@ static void b43_phy_ht_tx_power_fix(struct b43_wldev *dev)
}
}

+#if 0
+static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable)
+{
+ struct b43_phy_ht *phy_ht = dev->phy.ht;
+ u16 en_bits = B43_PHY_HT_TXPCTL_CMD_C1_COEFF |
+ B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN |
+ B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN;
+ const u16 cmd_regs[3] = { B43_PHY_HT_TXPCTL_CMD_C1,
+ B43_PHY_HT_TXPCTL_CMD_C2,
+ B43_PHY_HT_TXPCTL_CMD_C3 };
+ int i;
+
+ if (!enable) {
+ if (b43_phy_read(dev, B43_PHY_HT_TXPCTL_CMD_C1) & en_bits) {
+ /* We disable enabled TX pwr ctl, save it's state */
+ /*
+ * TODO: find the registers. On N-PHY they were 0x1ed
+ * and 0x1ee, we need 3 such a registers for HT-PHY
+ */
+ }
+ b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, ~en_bits);
+ } else {
+ b43_phy_set(dev, B43_PHY_HT_TXPCTL_CMD_C1, en_bits);
+
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+ for (i = 0; i < 3; i++)
+ b43_phy_write(dev, cmd_regs[i], 0x32);
+ }
+
+ for (i = 0; i < 3; i++)
+ if (phy_ht->tx_pwr_idx[i] <=
+ B43_PHY_HT_TXPCTL_CMD_C1_INIT)
+ b43_phy_write(dev, cmd_regs[i],
+ phy_ht->tx_pwr_idx[i]);
+ }
+
+ phy_ht->tx_pwr_ctl = enable;
+}
+#endif
+
/**************************************************
* Channel switching ops.
**************************************************/
@@ -455,14 +495,21 @@ static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_ht *phy_ht = phy->ht;
+ int i;

memset(phy_ht, 0, sizeof(*phy_ht));
+
+ phy_ht->tx_pwr_ctl = true;
+ for (i = 0; i < 3; i++)
+ phy_ht->tx_pwr_idx[i] = B43_PHY_HT_TXPCTL_CMD_C1_INIT + 1;
}

static int b43_phy_ht_op_init(struct b43_wldev *dev)
{
+ struct b43_phy_ht *phy_ht = dev->phy.ht;
u16 tmp;
u16 clip_state[3];
+ bool saved_tx_pwr_ctl;

if (dev->dev->bus_type != B43_BUS_BCMA) {
b43err(dev->wl, "HT-PHY is supported only on BCMA bus!\n");
@@ -589,6 +636,14 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
b43_httab_write_bulk(dev, B43_HTTAB32(0x1a, 0xc0),
B43_HTTAB_1A_C0_LATE_SIZE, b43_httab_0x1a_0xc0_late);

+ saved_tx_pwr_ctl = phy_ht->tx_pwr_ctl;
+ b43_phy_ht_tx_power_fix(dev);
+#if 0
+ b43_phy_ht_tx_power_ctl(dev, false);
+ /* TODO */
+ b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl);
+#endif
+
return 0;
}

diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index 684807c..bc7a43f 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -22,6 +22,13 @@
#define B43_PHY_HT_BW4 0x1D1
#define B43_PHY_HT_BW5 0x1D2
#define B43_PHY_HT_BW6 0x1D3
+#define B43_PHY_HT_TXPCTL_CMD_C1 0x1E7 /* TX power control command */
+#define B43_PHY_HT_TXPCTL_CMD_C1_INIT 0x007F /* Init */
+#define B43_PHY_HT_TXPCTL_CMD_C1_COEFF 0x2000 /* Power control coefficients */
+#define B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN 0x4000 /* Hardware TX power control enable */
+#define B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN 0x8000 /* TX power control enable */
+#define B43_PHY_HT_TXPCTL_CMD_C2 0x222
+#define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F

#define B43_PHY_HT_C1_CLIP1THRES B43_PHY_OFDM(0x00E)
#define B43_PHY_HT_C2_CLIP1THRES B43_PHY_OFDM(0x04E)
@@ -51,6 +58,9 @@
#define B43_PHY_HT_AFE_C3_OVER B43_PHY_EXTG(0x118)
#define B43_PHY_HT_AFE_C3 B43_PHY_EXTG(0x119)

+#define B43_PHY_HT_TXPCTL_CMD_C3 B43_PHY_EXTG(0x164)
+#define B43_PHY_HT_TXPCTL_CMD_C3_INIT 0x007F
+
#define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A)


@@ -67,6 +77,9 @@ struct b43_phy_ht_channeltab_e_phy {

struct b43_phy_ht {
u16 rf_ctl_int_save[3];
+
+ bool tx_pwr_ctl;
+ u8 tx_pwr_idx[3];
};


--
1.7.10.4


2013-03-07 16:35:35

by Michael Büsch

[permalink] [raw]
Subject: Re: [PATCH 11/13] b43: HT-PHY: implement RSSI polling

On Thu, 7 Mar 2013 16:47:25 +0100
Rafał Miłecki <[email protected]> wrote:

> + const u16 ctl_regs[3][2] = {
> + { B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER, },
> + { B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER, },
> + { B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER, },
> + };
> + const u16 radio_r[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1, };

> + u16 phy_regs_to_save[] = {
> + B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER,
> + 0x848, 0x841,
> + B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER,
> + 0x868, 0x861,
> + B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER,
> + 0x888, 0x881,
> + };

It usually is better to define tables that are constant as "static const",
so that they are not put on the kernel stack.

--
Michael


Attachments:
signature.asc (836.00 B)

2013-03-14 14:58:48

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH 00/13] b43: implement basic TX power mgmt

On Thu, 2013-03-14 at 00:19 +0100, Rafał Miłecki wrote:
>
> > If you have a git tree I can pull this from, I'd be happy to give it
> > some testing...
>
> You can try wireless-testing:
> http://git.kernel.org/cgit/linux/kernel/git/linville/wireless-testing.git

Thanks. This is not an improvement here.

Sitting at my desk, about 5m from my WNDR3800 access point with walls
and chimney in between them, I was previously seeing a TX rate of 48Mb/s
up to 54Mb/s (reported by 'iwconfig wlan0' and also as the RX rate for
the corresponding wireless client in OpenWRT's status page).

A primitive test copying a 143MiB file to a wired host would take 35
seconds, averaging 4.1MiB/s.

With these changes I get TX rates of about 18-24Mb/s and copying the
same file takes 82 seconds, averaging 1.7MiB/s

That's comparing the Fedora 3.8.2-206.fc18.x86_64 kernel with current
wireless-testing, rather than wireless-testing from before and after
your changes. But that shouldn't matter, presumably?

Do you want me to do some more specific tests?

--
dwmw2


Attachments:
smime.p7s (6.03 kB)

2013-03-07 18:55:06

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 00/13] b43: implement basic TX power mgmt

2013/3/7 Larry Finger <[email protected]>:
> On 03/07/2013 09:47 AM, Rafał Miłecki wrote:
>>
>> After spotting a lot of N-PHY-similar functions in
>> BCM4331 dump of MMIO ops - split into names parts
>> I was able to finally improve HT-PHY code.
>>
>> It now sets TX basically, I can finally talk with devices that are few
>> meters away, not just few centimetres. It's a little patch bomb, sorry
>> for that, but I wasn't sure if my code is correct until it was complete
>> and started working.
>>
>> Rafał Miłecki (13):
>> b43: HT-PHY: rename AFE defines
>> b43: HT-PHY: add classifier control function
>> b43: HT-PHY: move TX fix to the separated function
>> b43: HT-PHY: implement spurious tone avoidance
>> b43: HT-PHY: implement MAC reclocking
>> b43: HT-PHY: implement CCA reset
>> b43: HT-PHY: implement PA override
>> b43: HT-PHY: implement controlling TX power control
>> b43: HT-PHY: implement stopping sample tone playback
>> b43: HT-PHY: implement playing sample tone
>> b43: HT-PHY: implement RSSI polling
>> b43: HT-PHY: setup TX power control
>> b43: HT-PHY: enable basic TX power setup
>>
>> drivers/net/wireless/b43/phy_ht.c | 603
>> +++++++++++++++++++++++++++++++++----
>> drivers/net/wireless/b43/phy_ht.h | 77 ++++-
>> 2 files changed, 613 insertions(+), 67 deletions(-)
>
>
> What tree is used for these patches? Numbers 1-7 applied with offsets, and
> some fuzz. Number 8 failed, and I quit trying there. I am using
> wireless-testing that was a fresh pull yesterday after John rebased it.

I've just checkouted origin/master again, to make sure everything is
clean, and patches applied fine. Please make sure you're using latest
wireless-testing like a
http://git.kernel.org/cgit/linux/kernel/git/linville/wireless-testing.git/commit/?id=12c18c7a3d8f20366424834b20be40f7f3a9e2c2

--
Rafał

2013-03-07 15:48:02

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 09/13] b43: HT-PHY: implement stopping sample tone playback

It was another sequence I recognized in HT-PHY dump:
phy_read(0x00c7) -> 0x0001
phy_read(0x00c3) -> 0x0000
phy_write(0x00c3) <- 0x0002
phy_read(0x00c3) -> 0x0000
phy_write(0x00c3) <- 0x0000
The difference to N-PHY is that it writes to 6 tables instead of a one
(after above).

Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_ht.c | 41 +++++++++++++++++++++++++++++++++++++
drivers/net/wireless/b43/phy_ht.h | 6 ++++++
2 files changed, 47 insertions(+)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 4300867..8e5d5bd 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -294,6 +294,36 @@ static void b43_phy_ht_bphy_init(struct b43_wldev *dev)
}

/**************************************************
+ * Samples
+ **************************************************/
+
+#if 0
+static void b43_phy_ht_stop_playback(struct b43_wldev *dev)
+{
+ struct b43_phy_ht *phy_ht = dev->phy.ht;
+ u16 tmp;
+ int i;
+
+ tmp = b43_phy_read(dev, B43_PHY_HT_SAMP_STAT);
+ if (tmp & 0x1)
+ b43_phy_set(dev, B43_PHY_HT_SAMP_CMD, B43_PHY_HT_SAMP_CMD_STOP);
+ else if (tmp & 0x2)
+ b43_phy_mask(dev, B43_PHY_HT_IQLOCAL_CMDGCTL, 0x7FFF);
+
+ b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0x0004);
+
+ for (i = 0; i < 3; i++) {
+ if (phy_ht->bb_mult_save[i] >= 0) {
+ b43_httab_write(dev, B43_HTTAB16(13, 0x63 + i * 4),
+ phy_ht->bb_mult_save[i]);
+ b43_httab_write(dev, B43_HTTAB16(13, 0x67 + i * 4),
+ phy_ht->bb_mult_save[i]);
+ }
+ }
+}
+#endif
+
+/**************************************************
* Tx/Rx
**************************************************/

@@ -357,6 +387,13 @@ static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable)

phy_ht->tx_pwr_ctl = enable;
}
+
+static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
+{
+ /* TODO */
+ b43_phy_ht_stop_playback(dev);
+ /* TODO */
+}
#endif

/**************************************************
@@ -502,6 +539,9 @@ static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev)
phy_ht->tx_pwr_ctl = true;
for (i = 0; i < 3; i++)
phy_ht->tx_pwr_idx[i] = B43_PHY_HT_TXPCTL_CMD_C1_INIT + 1;
+
+ for (i = 0; i < 3; i++)
+ phy_ht->bb_mult_save[i] = -1;
}

static int b43_phy_ht_op_init(struct b43_wldev *dev)
@@ -640,6 +680,7 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
b43_phy_ht_tx_power_fix(dev);
#if 0
b43_phy_ht_tx_power_ctl(dev, false);
+ b43_phy_ht_tx_power_ctl_idle_tssi(dev);
/* TODO */
b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl);
#endif
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index bc7a43f..7ec794b 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -16,6 +16,10 @@
#define B43_PHY_HT_CLASS_CTL_CCK_EN 0x0001 /* CCK enable */
#define B43_PHY_HT_CLASS_CTL_OFDM_EN 0x0002 /* OFDM enable */
#define B43_PHY_HT_CLASS_CTL_WAITED_EN 0x0004 /* Waited enable */
+#define B43_PHY_HT_IQLOCAL_CMDGCTL 0x0C2 /* I/Q LO cal command G control */
+#define B43_PHY_HT_SAMP_CMD 0x0C3 /* Sample command */
+#define B43_PHY_HT_SAMP_CMD_STOP 0x0002 /* Stop */
+#define B43_PHY_HT_SAMP_STAT 0x0C7 /* Sample status */
#define B43_PHY_HT_BW1 0x1CE
#define B43_PHY_HT_BW2 0x1CF
#define B43_PHY_HT_BW3 0x1D0
@@ -80,6 +84,8 @@ struct b43_phy_ht {

bool tx_pwr_ctl;
u8 tx_pwr_idx[3];
+
+ s32 bb_mult_save[3];
};


--
1.7.10.4


2013-03-09 12:43:57

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH V3 01/13] b43: HT-PHY: rename AFE defines

It you take a look at N-PHY analog switch function it touches every core
on the chipset. It seems HT-PHY does they same, it just has 3 cores
instead of 2 (which make sense since BCM4331 is 3x3). Rename AFE defines
to include core id.

Signed-off-by: Rafał Miłecki <[email protected]>
---
V2: make ctl_regs array static btw
V3: use correct --in-reply-to

Sorry for using wrong In-Reply-To in V2 :(
---
drivers/net/wireless/b43/phy_ht.c | 38 ++++++++++++++++++-------------------
drivers/net/wireless/b43/phy_ht.h | 12 ++++++------
2 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 3719a88..df07c83 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -176,10 +176,10 @@ static void b43_phy_ht_afe_unk1(struct b43_wldev *dev)
{
u8 i;

- const u16 ctl_regs[3][2] = {
- { B43_PHY_HT_AFE_CTL1, B43_PHY_HT_AFE_CTL2 },
- { B43_PHY_HT_AFE_CTL3, B43_PHY_HT_AFE_CTL4 },
- { B43_PHY_HT_AFE_CTL5, B43_PHY_HT_AFE_CTL6},
+ static const u16 ctl_regs[3][2] = {
+ { B43_PHY_HT_AFE_C1_OVER, B43_PHY_HT_AFE_C1 },
+ { B43_PHY_HT_AFE_C2_OVER, B43_PHY_HT_AFE_C2 },
+ { B43_PHY_HT_AFE_C3_OVER, B43_PHY_HT_AFE_C3},
};

for (i = 0; i < 3; i++) {
@@ -362,9 +362,9 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)

b43_phy_mask(dev, B43_PHY_EXTG(0), ~0x3);

- b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0);

b43_phy_write(dev, B43_PHY_EXTG(0x103), 0x20);
b43_phy_write(dev, B43_PHY_EXTG(0x101), 0x20);
@@ -511,19 +511,19 @@ static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev,
static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on)
{
if (on) {
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00cd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x0000);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00cd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x0000);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00cd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x0000);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1, 0x00cd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0x0000);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2, 0x00cd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0x0000);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3, 0x00cd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0x0000);
} else {
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x07ff);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00fd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x07ff);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00fd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x07ff);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00fd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0x07ff);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1, 0x00fd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0x07ff);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2, 0x00fd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0x07ff);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3, 0x00fd);
}
}

diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index 6544c42..60824fa 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -36,12 +36,12 @@

#define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010)

-#define B43_PHY_HT_AFE_CTL1 B43_PHY_EXTG(0x110)
-#define B43_PHY_HT_AFE_CTL2 B43_PHY_EXTG(0x111)
-#define B43_PHY_HT_AFE_CTL3 B43_PHY_EXTG(0x114)
-#define B43_PHY_HT_AFE_CTL4 B43_PHY_EXTG(0x115)
-#define B43_PHY_HT_AFE_CTL5 B43_PHY_EXTG(0x118)
-#define B43_PHY_HT_AFE_CTL6 B43_PHY_EXTG(0x119)
+#define B43_PHY_HT_AFE_C1_OVER B43_PHY_EXTG(0x110)
+#define B43_PHY_HT_AFE_C1 B43_PHY_EXTG(0x111)
+#define B43_PHY_HT_AFE_C2_OVER B43_PHY_EXTG(0x114)
+#define B43_PHY_HT_AFE_C2 B43_PHY_EXTG(0x115)
+#define B43_PHY_HT_AFE_C3_OVER B43_PHY_EXTG(0x118)
+#define B43_PHY_HT_AFE_C3 B43_PHY_EXTG(0x119)


/* Values for PHY registers used on channel switching */
--
1.7.10.4


2013-03-07 15:48:06

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 11/13] b43: HT-PHY: implement RSSI polling


Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_ht.c | 96 ++++++++++++++++++++++++++++++++++++-
drivers/net/wireless/b43/phy_ht.h | 5 ++
2 files changed, 100 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 363c64c..831dca4 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -388,6 +388,92 @@ static void b43_phy_ht_tx_tone(struct b43_wldev *dev)
#endif

/**************************************************
+ * RSSI
+ **************************************************/
+
+#if 0
+static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel,
+ u8 rssi_type)
+{
+ const u16 ctl_regs[3][2] = {
+ { B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER, },
+ { B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER, },
+ { B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER, },
+ };
+ const u16 radio_r[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1, };
+ int core;
+
+ if (core_sel == 0) {
+ b43err(dev->wl, "RSSI selection for core off not implemented yet\n");
+ } else {
+ for (core = 0; core < 3; core++) {
+ /* Check if caller requested a one specific core */
+ if ((core_sel == 1 && core != 0) ||
+ (core_sel == 2 && core != 1) ||
+ (core_sel == 3 && core != 2))
+ continue;
+
+ switch (rssi_type) {
+ case 4:
+ b43_phy_set(dev, ctl_regs[core][0], 0x3 << 8);
+ b43_phy_set(dev, ctl_regs[core][0], 0x3 << 10);
+ b43_phy_set(dev, ctl_regs[core][1], 0x1 << 9);
+ b43_phy_set(dev, ctl_regs[core][1], 0x1 << 10);
+
+ b43_radio_set(dev, R2059_RXRX1 | 0xbf, 0x1);
+ b43_radio_write(dev, radio_r[core] | 0x159,
+ 0x11);
+ break;
+ default:
+ b43err(dev->wl, "RSSI selection for type %d not implemented yet\n",
+ rssi_type);
+ }
+ }
+ }
+}
+
+static void b43_phy_ht_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
+ u8 nsamp)
+{
+ u16 phy_regs_values[12];
+ u16 phy_regs_to_save[] = {
+ B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER,
+ 0x848, 0x841,
+ B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER,
+ 0x868, 0x861,
+ B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER,
+ 0x888, 0x881,
+ };
+ u16 tmp[3];
+ int i;
+
+ for (i = 0; i < 12; i++)
+ phy_regs_values[i] = b43_phy_read(dev, phy_regs_to_save[i]);
+
+ b43_phy_ht_rssi_select(dev, 5, type);
+
+ for (i = 0; i < 6; i++)
+ buf[i] = 0;
+
+ for (i = 0; i < nsamp; i++) {
+ tmp[0] = b43_phy_read(dev, B43_PHY_HT_RSSI_C1);
+ tmp[1] = b43_phy_read(dev, B43_PHY_HT_RSSI_C2);
+ tmp[2] = b43_phy_read(dev, B43_PHY_HT_RSSI_C3);
+
+ buf[0] += ((s8)((tmp[0] & 0x3F) << 2)) >> 2;
+ buf[1] += ((s8)(((tmp[0] >> 8) & 0x3F) << 2)) >> 2;
+ buf[2] += ((s8)((tmp[1] & 0x3F) << 2)) >> 2;
+ buf[3] += ((s8)(((tmp[1] >> 8) & 0x3F) << 2)) >> 2;
+ buf[4] += ((s8)((tmp[2] & 0x3F) << 2)) >> 2;
+ buf[5] += ((s8)(((tmp[2] >> 8) & 0x3F) << 2)) >> 2;
+ }
+
+ for (i = 0; i < 12; i++)
+ b43_phy_write(dev, phy_regs_to_save[i], phy_regs_values[i]);
+}
+#endif
+
+/**************************************************
* Tx/Rx
**************************************************/

@@ -454,12 +540,20 @@ static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable)

static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
{
+ struct b43_phy_ht *phy_ht = dev->phy.ht;
+ s32 rssi_buf[6];
+
/* TODO */

b43_phy_ht_tx_tone(dev);
udelay(20);
- /* TODO: poll RSSI */
+ b43_phy_ht_poll_rssi(dev, 4, rssi_buf, 1);
b43_phy_ht_stop_playback(dev);
+ b43_phy_ht_reset_cca(dev);
+
+ phy_ht->idle_tssi[0] = rssi_buf[0] & 0xff;
+ phy_ht->idle_tssi[1] = rssi_buf[2] & 0xff;
+ phy_ht->idle_tssi[2] = rssi_buf[4] & 0xff;

/* TODO */
}
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index c517958..165c501 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -36,6 +36,9 @@
#define B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN 0x8000 /* TX power control enable */
#define B43_PHY_HT_TXPCTL_CMD_C2 0x222
#define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F
+#define B43_PHY_HT_RSSI_C1 0x219
+#define B43_PHY_HT_RSSI_C2 0x21A
+#define B43_PHY_HT_RSSI_C3 0x21B

#define B43_PHY_HT_C1_CLIP1THRES B43_PHY_OFDM(0x00E)
#define B43_PHY_HT_C2_CLIP1THRES B43_PHY_OFDM(0x04E)
@@ -91,6 +94,8 @@ struct b43_phy_ht {
u8 tx_pwr_idx[3];

s32 bb_mult_save[3];
+
+ u8 idle_tssi[3];
};


--
1.7.10.4


2013-03-09 12:56:35

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH V2 11/13] b43: HT-PHY: implement RSSI polling

Signed-off-by: Rafał Miłecki <[email protected]>
---
V2: use static const where possible (for arrays)
---
drivers/net/wireless/b43/phy_ht.c | 96 ++++++++++++++++++++++++++++++++++++-
drivers/net/wireless/b43/phy_ht.h | 5 ++
2 files changed, 100 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 22fdde6..ae9cd29 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -388,6 +388,92 @@ static void b43_phy_ht_tx_tone(struct b43_wldev *dev)
#endif

/**************************************************
+ * RSSI
+ **************************************************/
+
+#if 0
+static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel,
+ u8 rssi_type)
+{
+ static const u16 ctl_regs[3][2] = {
+ { B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER, },
+ { B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER, },
+ { B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER, },
+ };
+ static const u16 radio_r[] = { R2059_SYN, R2059_TXRX0, R2059_RXRX1, };
+ int core;
+
+ if (core_sel == 0) {
+ b43err(dev->wl, "RSSI selection for core off not implemented yet\n");
+ } else {
+ for (core = 0; core < 3; core++) {
+ /* Check if caller requested a one specific core */
+ if ((core_sel == 1 && core != 0) ||
+ (core_sel == 2 && core != 1) ||
+ (core_sel == 3 && core != 2))
+ continue;
+
+ switch (rssi_type) {
+ case 4:
+ b43_phy_set(dev, ctl_regs[core][0], 0x3 << 8);
+ b43_phy_set(dev, ctl_regs[core][0], 0x3 << 10);
+ b43_phy_set(dev, ctl_regs[core][1], 0x1 << 9);
+ b43_phy_set(dev, ctl_regs[core][1], 0x1 << 10);
+
+ b43_radio_set(dev, R2059_RXRX1 | 0xbf, 0x1);
+ b43_radio_write(dev, radio_r[core] | 0x159,
+ 0x11);
+ break;
+ default:
+ b43err(dev->wl, "RSSI selection for type %d not implemented yet\n",
+ rssi_type);
+ }
+ }
+ }
+}
+
+static void b43_phy_ht_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
+ u8 nsamp)
+{
+ u16 phy_regs_values[12];
+ static const u16 phy_regs_to_save[] = {
+ B43_PHY_HT_AFE_C1, B43_PHY_HT_AFE_C1_OVER,
+ 0x848, 0x841,
+ B43_PHY_HT_AFE_C2, B43_PHY_HT_AFE_C2_OVER,
+ 0x868, 0x861,
+ B43_PHY_HT_AFE_C3, B43_PHY_HT_AFE_C3_OVER,
+ 0x888, 0x881,
+ };
+ u16 tmp[3];
+ int i;
+
+ for (i = 0; i < 12; i++)
+ phy_regs_values[i] = b43_phy_read(dev, phy_regs_to_save[i]);
+
+ b43_phy_ht_rssi_select(dev, 5, type);
+
+ for (i = 0; i < 6; i++)
+ buf[i] = 0;
+
+ for (i = 0; i < nsamp; i++) {
+ tmp[0] = b43_phy_read(dev, B43_PHY_HT_RSSI_C1);
+ tmp[1] = b43_phy_read(dev, B43_PHY_HT_RSSI_C2);
+ tmp[2] = b43_phy_read(dev, B43_PHY_HT_RSSI_C3);
+
+ buf[0] += ((s8)((tmp[0] & 0x3F) << 2)) >> 2;
+ buf[1] += ((s8)(((tmp[0] >> 8) & 0x3F) << 2)) >> 2;
+ buf[2] += ((s8)((tmp[1] & 0x3F) << 2)) >> 2;
+ buf[3] += ((s8)(((tmp[1] >> 8) & 0x3F) << 2)) >> 2;
+ buf[4] += ((s8)((tmp[2] & 0x3F) << 2)) >> 2;
+ buf[5] += ((s8)(((tmp[2] >> 8) & 0x3F) << 2)) >> 2;
+ }
+
+ for (i = 0; i < 12; i++)
+ b43_phy_write(dev, phy_regs_to_save[i], phy_regs_values[i]);
+}
+#endif
+
+/**************************************************
* Tx/Rx
**************************************************/

@@ -454,12 +540,20 @@ static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable)

static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
{
+ struct b43_phy_ht *phy_ht = dev->phy.ht;
+ s32 rssi_buf[6];
+
/* TODO */

b43_phy_ht_tx_tone(dev);
udelay(20);
- /* TODO: poll RSSI */
+ b43_phy_ht_poll_rssi(dev, 4, rssi_buf, 1);
b43_phy_ht_stop_playback(dev);
+ b43_phy_ht_reset_cca(dev);
+
+ phy_ht->idle_tssi[0] = rssi_buf[0] & 0xff;
+ phy_ht->idle_tssi[1] = rssi_buf[2] & 0xff;
+ phy_ht->idle_tssi[2] = rssi_buf[4] & 0xff;

/* TODO */
}
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index c517958..165c501 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -36,6 +36,9 @@
#define B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN 0x8000 /* TX power control enable */
#define B43_PHY_HT_TXPCTL_CMD_C2 0x222
#define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F
+#define B43_PHY_HT_RSSI_C1 0x219
+#define B43_PHY_HT_RSSI_C2 0x21A
+#define B43_PHY_HT_RSSI_C3 0x21B

#define B43_PHY_HT_C1_CLIP1THRES B43_PHY_OFDM(0x00E)
#define B43_PHY_HT_C2_CLIP1THRES B43_PHY_OFDM(0x04E)
@@ -91,6 +94,8 @@ struct b43_phy_ht {
u8 tx_pwr_idx[3];

s32 bb_mult_save[3];
+
+ u8 idle_tssi[3];
};


--
1.7.10.4


2013-03-07 15:47:53

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 06/13] b43: HT-PHY: implement CCA reset

It was just another similar-to-N-PHY and easy-to-track routine:
write32 0xb0601408 <- 0x00002057
phy_read(0x0001) -> 0x0000
phy_write(0x0001) <- 0x4000
phy_write(0x0001) <- 0x0000
write32 0xb0601408 <- 0x00002055
(b43_phy_ht_force_rf_sequence was moved up unmodified)

Signed-off-by: Rafał Miłecki <[email protected]>
---
P.S.
There is a "msleep" usage warning, but it's in the code I just move. Will fix
sleeps/waits later globally.
---
drivers/net/wireless/b43/phy_ht.c | 68 +++++++++++++++++++++++++------------
1 file changed, 47 insertions(+), 21 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 4b24816..aedbae7 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -154,6 +154,31 @@ static void b43_radio_2059_init(struct b43_wldev *dev)
}

/**************************************************
+ * RF
+ **************************************************/
+
+static void b43_phy_ht_force_rf_sequence(struct b43_wldev *dev, u16 rf_seq)
+{
+ u8 i;
+
+ u16 save_seq_mode = b43_phy_read(dev, B43_PHY_HT_RF_SEQ_MODE);
+ b43_phy_set(dev, B43_PHY_HT_RF_SEQ_MODE, 0x3);
+
+ b43_phy_set(dev, B43_PHY_HT_RF_SEQ_TRIG, rf_seq);
+ for (i = 0; i < 200; i++) {
+ if (!(b43_phy_read(dev, B43_PHY_HT_RF_SEQ_STATUS) & rf_seq)) {
+ i = 0;
+ break;
+ }
+ msleep(1);
+ }
+ if (i)
+ b43err(dev->wl, "Forcing RF sequence timeout\n");
+
+ b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode);
+}
+
+/**************************************************
* Various PHY ops
**************************************************/

@@ -173,6 +198,20 @@ static u16 b43_phy_ht_classifier(struct b43_wldev *dev, u16 mask, u16 val)
return tmp;
}

+static void b43_phy_ht_reset_cca(struct b43_wldev *dev)
+{
+ u16 bbcfg;
+
+ b43_phy_force_clock(dev, true);
+ bbcfg = b43_phy_read(dev, B43_PHY_HT_BBCFG);
+ b43_phy_write(dev, B43_PHY_HT_BBCFG, bbcfg | B43_PHY_HT_BBCFG_RSTCCA);
+ udelay(1);
+ b43_phy_write(dev, B43_PHY_HT_BBCFG, bbcfg & ~B43_PHY_HT_BBCFG_RSTCCA);
+ b43_phy_force_clock(dev, false);
+
+ b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX);
+}
+
static void b43_phy_ht_zero_extg(struct b43_wldev *dev)
{
u8 i, j;
@@ -209,27 +248,6 @@ static void b43_phy_ht_afe_unk1(struct b43_wldev *dev)
}
}

-static void b43_phy_ht_force_rf_sequence(struct b43_wldev *dev, u16 rf_seq)
-{
- u8 i;
-
- u16 save_seq_mode = b43_phy_read(dev, B43_PHY_HT_RF_SEQ_MODE);
- b43_phy_set(dev, B43_PHY_HT_RF_SEQ_MODE, 0x3);
-
- b43_phy_set(dev, B43_PHY_HT_RF_SEQ_TRIG, rf_seq);
- for (i = 0; i < 200; i++) {
- if (!(b43_phy_read(dev, B43_PHY_HT_RF_SEQ_STATUS) & rf_seq)) {
- i = 0;
- break;
- }
- msleep(1);
- }
- if (i)
- b43err(dev->wl, "Forcing RF sequence timeout\n");
-
- b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode);
-}
-
static void b43_phy_ht_read_clip_detection(struct b43_wldev *dev, u16 *clip_st)
{
clip_st[0] = b43_phy_read(dev, B43_PHY_HT_C1_CLIP1THRES);
@@ -319,6 +337,14 @@ static void b43_phy_ht_spur_avoid(struct b43_wldev *dev,
b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);

/* TODO: reset PLL */
+
+ if (spuravoid)
+ b43_phy_set(dev, B43_PHY_HT_BBCFG, B43_PHY_HT_BBCFG_RSTRX);
+ else
+ b43_phy_mask(dev, B43_PHY_HT_BBCFG,
+ ~B43_PHY_HT_BBCFG_RSTRX & 0xFFFF);
+
+ b43_phy_ht_reset_cca(dev);
}

static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
--
1.7.10.4


2013-03-13 10:41:29

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH 00/13] b43: implement basic TX power mgmt

On Thu, 2013-03-07 at 16:47 +0100, Rafał Miłecki wrote:
> After spotting a lot of N-PHY-similar functions in
> BCM4331 dump of MMIO ops - split into names parts
> I was able to finally improve HT-PHY code.
>
> It now sets TX basically, I can finally talk with devices that are few
> meters away, not just few centimetres. It's a little patch bomb, sorry
> for that, but I wasn't sure if my code is correct until it was complete
> and started working.

If you have a git tree I can pull this from, I'd be happy to give it
some testing...

--
dwmw2


Attachments:
smime.p7s (6.03 kB)

2013-03-18 21:30:51

by David Woodhouse

[permalink] [raw]
Subject: Re: [PATCH 00/13] b43: implement basic TX power mgmt

On Sat, 2013-03-16 at 14:50 +0100, Rafał Miłecki wrote:
> To verify my theory, could you try reverting
> 4969b41798e512689bba57c8c44d873216eba814, AKA
> b43: HT-PHY: enable basic TX power setup
> ? Does reverting this patch brings you back ~4.1MiB/s?

Fairly much, yes.

--
dwmw2


Attachments:
smime.p7s (6.03 kB)

2013-03-07 15:48:04

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 10/13] b43: HT-PHY: implement playing sample tone


Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_ht.c | 69 +++++++++++++++++++++++++++++++++++++
drivers/net/wireless/b43/phy_ht.h | 5 +++
2 files changed, 74 insertions(+)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 8e5d5bd..363c64c 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -321,6 +321,70 @@ static void b43_phy_ht_stop_playback(struct b43_wldev *dev)
}
}
}
+
+static u16 b43_phy_ht_load_samples(struct b43_wldev *dev)
+{
+ int i;
+ u16 len = 20 << 3;
+
+ b43_phy_write(dev, B43_PHY_HT_TABLE_ADDR, 0x4400);
+
+ for (i = 0; i < len; i++) {
+ b43_phy_write(dev, B43_PHY_HT_TABLE_DATAHI, 0);
+ b43_phy_write(dev, B43_PHY_HT_TABLE_DATALO, 0);
+ }
+
+ return len;
+}
+
+static void b43_phy_ht_run_samples(struct b43_wldev *dev, u16 samps, u16 loops,
+ u16 wait)
+{
+ struct b43_phy_ht *phy_ht = dev->phy.ht;
+ u16 save_seq_mode;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ if (phy_ht->bb_mult_save[i] < 0)
+ phy_ht->bb_mult_save[i] = b43_httab_read(dev, B43_HTTAB16(13, 0x63 + i * 4));
+ }
+
+ b43_phy_write(dev, B43_PHY_HT_SAMP_DEP_CNT, samps - 1);
+ if (loops != 0xFFFF)
+ loops--;
+ b43_phy_write(dev, B43_PHY_HT_SAMP_LOOP_CNT, loops);
+ b43_phy_write(dev, B43_PHY_HT_SAMP_WAIT_CNT, wait);
+
+ save_seq_mode = b43_phy_read(dev, B43_PHY_HT_RF_SEQ_MODE);
+ b43_phy_set(dev, B43_PHY_HT_RF_SEQ_MODE,
+ B43_PHY_HT_RF_SEQ_MODE_CA_OVER);
+
+ /* TODO: find out mask bits! Do we need more function arguments? */
+ b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0);
+ b43_phy_mask(dev, B43_PHY_HT_SAMP_CMD, ~0);
+ b43_phy_mask(dev, B43_PHY_HT_IQLOCAL_CMDGCTL, ~0);
+ b43_phy_set(dev, B43_PHY_HT_SAMP_CMD, 0x1);
+
+ for (i = 0; i < 100; i++) {
+ if (!(b43_phy_read(dev, B43_PHY_HT_RF_SEQ_STATUS) & 1)) {
+ i = 0;
+ break;
+ }
+ udelay(10);
+ }
+ if (i)
+ b43err(dev->wl, "run samples timeout\n");
+
+ b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode);
+}
+
+static void b43_phy_ht_tx_tone(struct b43_wldev *dev)
+{
+ u16 samp;
+
+ samp = b43_phy_ht_load_samples(dev);
+ b43_phy_ht_run_samples(dev, samp, 0xFFFF, 0);
+}
#endif

/**************************************************
@@ -391,7 +455,12 @@ static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable)
static void b43_phy_ht_tx_power_ctl_idle_tssi(struct b43_wldev *dev)
{
/* TODO */
+
+ b43_phy_ht_tx_tone(dev);
+ udelay(20);
+ /* TODO: poll RSSI */
b43_phy_ht_stop_playback(dev);
+
/* TODO */
}
#endif
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index 7ec794b..c517958 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -19,6 +19,9 @@
#define B43_PHY_HT_IQLOCAL_CMDGCTL 0x0C2 /* I/Q LO cal command G control */
#define B43_PHY_HT_SAMP_CMD 0x0C3 /* Sample command */
#define B43_PHY_HT_SAMP_CMD_STOP 0x0002 /* Stop */
+#define B43_PHY_HT_SAMP_LOOP_CNT 0x0C4 /* Sample loop count */
+#define B43_PHY_HT_SAMP_WAIT_CNT 0x0C5 /* Sample wait count */
+#define B43_PHY_HT_SAMP_DEP_CNT 0x0C6 /* Sample depth count */
#define B43_PHY_HT_SAMP_STAT 0x0C7 /* Sample status */
#define B43_PHY_HT_BW1 0x1CE
#define B43_PHY_HT_BW2 0x1CF
@@ -39,6 +42,8 @@
#define B43_PHY_HT_C3_CLIP1THRES B43_PHY_OFDM(0x08E)

#define B43_PHY_HT_RF_SEQ_MODE B43_PHY_EXTG(0x000)
+#define B43_PHY_HT_RF_SEQ_MODE_CA_OVER 0x0001 /* Core active override */
+#define B43_PHY_HT_RF_SEQ_MODE_TR_OVER 0x0002 /* Trigger override */
#define B43_PHY_HT_RF_SEQ_TRIG B43_PHY_EXTG(0x003)
#define B43_PHY_HT_RF_SEQ_TRIG_RX2TX 0x0001 /* RX2TX */
#define B43_PHY_HT_RF_SEQ_TRIG_TX2RX 0x0002 /* TX2RX */
--
1.7.10.4


2013-03-09 12:41:51

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH V2 01/13] b43: HT-PHY: rename AFE defines

It you take a look at N-PHY analog switch function it touches every core
on the chipset. It seems HT-PHY does they same, it just has 3 cores
instead of 2 (which make sense since BCM4331 is 3x3). Rename AFE defines
to include core id.

Signed-off-by: Rafał Miłecki <[email protected]>
---
V2: make ctl_regs array static btw
---
drivers/net/wireless/b43/phy_ht.c | 38 ++++++++++++++++++-------------------
drivers/net/wireless/b43/phy_ht.h | 12 ++++++------
2 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 3719a88..df07c83 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -176,10 +176,10 @@ static void b43_phy_ht_afe_unk1(struct b43_wldev *dev)
{
u8 i;

- const u16 ctl_regs[3][2] = {
- { B43_PHY_HT_AFE_CTL1, B43_PHY_HT_AFE_CTL2 },
- { B43_PHY_HT_AFE_CTL3, B43_PHY_HT_AFE_CTL4 },
- { B43_PHY_HT_AFE_CTL5, B43_PHY_HT_AFE_CTL6},
+ static const u16 ctl_regs[3][2] = {
+ { B43_PHY_HT_AFE_C1_OVER, B43_PHY_HT_AFE_C1 },
+ { B43_PHY_HT_AFE_C2_OVER, B43_PHY_HT_AFE_C2 },
+ { B43_PHY_HT_AFE_C3_OVER, B43_PHY_HT_AFE_C3},
};

for (i = 0; i < 3; i++) {
@@ -362,9 +362,9 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)

b43_phy_mask(dev, B43_PHY_EXTG(0), ~0x3);

- b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0);

b43_phy_write(dev, B43_PHY_EXTG(0x103), 0x20);
b43_phy_write(dev, B43_PHY_EXTG(0x101), 0x20);
@@ -511,19 +511,19 @@ static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev,
static void b43_phy_ht_op_switch_analog(struct b43_wldev *dev, bool on)
{
if (on) {
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00cd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x0000);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00cd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x0000);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00cd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x0000);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1, 0x00cd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0x0000);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2, 0x00cd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0x0000);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3, 0x00cd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0x0000);
} else {
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL1, 0x07ff);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL2, 0x00fd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL3, 0x07ff);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL4, 0x00fd);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL5, 0x07ff);
- b43_phy_write(dev, B43_PHY_HT_AFE_CTL6, 0x00fd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1_OVER, 0x07ff);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C1, 0x00fd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2_OVER, 0x07ff);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C2, 0x00fd);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3_OVER, 0x07ff);
+ b43_phy_write(dev, B43_PHY_HT_AFE_C3, 0x00fd);
}
}

diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index 6544c42..60824fa 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -36,12 +36,12 @@

#define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010)

-#define B43_PHY_HT_AFE_CTL1 B43_PHY_EXTG(0x110)
-#define B43_PHY_HT_AFE_CTL2 B43_PHY_EXTG(0x111)
-#define B43_PHY_HT_AFE_CTL3 B43_PHY_EXTG(0x114)
-#define B43_PHY_HT_AFE_CTL4 B43_PHY_EXTG(0x115)
-#define B43_PHY_HT_AFE_CTL5 B43_PHY_EXTG(0x118)
-#define B43_PHY_HT_AFE_CTL6 B43_PHY_EXTG(0x119)
+#define B43_PHY_HT_AFE_C1_OVER B43_PHY_EXTG(0x110)
+#define B43_PHY_HT_AFE_C1 B43_PHY_EXTG(0x111)
+#define B43_PHY_HT_AFE_C2_OVER B43_PHY_EXTG(0x114)
+#define B43_PHY_HT_AFE_C2 B43_PHY_EXTG(0x115)
+#define B43_PHY_HT_AFE_C3_OVER B43_PHY_EXTG(0x118)
+#define B43_PHY_HT_AFE_C3 B43_PHY_EXTG(0x119)


/* Values for PHY registers used on channel switching */
--
1.7.10.4


2013-03-07 15:48:11

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 13/13] b43: HT-PHY: enable basic TX power setup


Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_ht.c | 9 ---------
1 file changed, 9 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 6d5eb04..54e5c85 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -297,7 +297,6 @@ static void b43_phy_ht_bphy_init(struct b43_wldev *dev)
* Samples
**************************************************/

-#if 0
static void b43_phy_ht_stop_playback(struct b43_wldev *dev)
{
struct b43_phy_ht *phy_ht = dev->phy.ht;
@@ -385,13 +384,11 @@ static void b43_phy_ht_tx_tone(struct b43_wldev *dev)
samp = b43_phy_ht_load_samples(dev);
b43_phy_ht_run_samples(dev, samp, 0xFFFF, 0);
}
-#endif

/**************************************************
* RSSI
**************************************************/

-#if 0
static void b43_phy_ht_rssi_select(struct b43_wldev *dev, u8 core_sel,
u8 rssi_type)
{
@@ -471,7 +468,6 @@ static void b43_phy_ht_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
for (i = 0; i < 12; i++)
b43_phy_write(dev, phy_regs_to_save[i], phy_regs_values[i]);
}
-#endif

/**************************************************
* Tx/Rx
@@ -499,7 +495,6 @@ static void b43_phy_ht_tx_power_fix(struct b43_wldev *dev)
}
}

-#if 0
static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable)
{
struct b43_phy_ht *phy_ht = dev->phy.ht;
@@ -665,7 +660,6 @@ static void b43_phy_ht_tx_power_ctl_setup(struct b43_wldev *dev)
b43_httab_write_bulk(dev, B43_HTTAB16(26 + c, 0), 64, regval);
}
}
-#endif

/**************************************************
* Channel switching ops.
@@ -949,13 +943,10 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)

saved_tx_pwr_ctl = phy_ht->tx_pwr_ctl;
b43_phy_ht_tx_power_fix(dev);
-#if 0
b43_phy_ht_tx_power_ctl(dev, false);
b43_phy_ht_tx_power_ctl_idle_tssi(dev);
b43_phy_ht_tx_power_ctl_setup(dev);
- /* TODO */
b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl);
-#endif

return 0;
}
--
1.7.10.4


2013-03-19 08:38:08

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 00/13] b43: implement basic TX power mgmt

2013/3/18 David Woodhouse <[email protected]>:
> On Sat, 2013-03-16 at 14:50 +0100, Rafał Miłecki wrote:
>> To verify my theory, could you try reverting
>> 4969b41798e512689bba57c8c44d873216eba814, AKA
>> b43: HT-PHY: enable basic TX power setup
>> ? Does reverting this patch brings you back ~4.1MiB/s?
>
> Fairly much, yes.

Thanks. I'll add workaround for your card, but it needs fixing reading
board info in ssb/bcma/b43.

--
Rafał

2013-03-07 15:47:49

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 04/13] b43: HT-PHY: implement spurious tone avoidance

On N-PHY it's also done after TX power fix, so it was easy to spot.
Unfortunately the MMIO logs I have from ndsiwrapper include channels
1-12 only, so enabling code for 13 and 14 is just a N-PHY-based guess.

Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_ht.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index f7463aa..4ccd371 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -285,6 +285,24 @@ static void b43_phy_ht_tx_power_fix(struct b43_wldev *dev)
* Channel switching ops.
**************************************************/

+static void b43_phy_ht_spur_avoid(struct b43_wldev *dev,
+ struct ieee80211_channel *new_channel)
+{
+ struct bcma_device *core = dev->dev->bdev;
+ int spuravoid = 0;
+
+ /* Check for 13 and 14 is just a guess, we don't have enough logs. */
+ if (new_channel->hw_value == 13 || new_channel->hw_value == 14)
+ spuravoid = 1;
+ bcma_core_pll_ctl(core, B43_BCMA_CLKCTLST_PHY_PLL_REQ, 0, false);
+ bcma_pmu_spuravoid_pllupdate(&core->bus->drv_cc, spuravoid);
+ bcma_core_pll_ctl(core,
+ B43_BCMA_CLKCTLST_80211_PLL_REQ |
+ B43_BCMA_CLKCTLST_PHY_PLL_REQ,
+ B43_BCMA_CLKCTLST_80211_PLL_ST |
+ B43_BCMA_CLKCTLST_PHY_PLL_ST, false);
+}
+
static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
const struct b43_phy_ht_channeltab_e_phy *e,
struct ieee80211_channel *new_channel)
@@ -318,6 +336,8 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
if (1) /* TODO: On N it's for early devices only, what about HT? */
b43_phy_ht_tx_power_fix(dev);

+ b43_phy_ht_spur_avoid(dev, new_channel);
+
b43_phy_write(dev, 0x017e, 0x3830);
}

--
1.7.10.4


2013-03-07 18:43:43

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 00/13] b43: implement basic TX power mgmt

2013/3/7 Larry Finger <[email protected]>:
> On 03/07/2013 09:47 AM, Rafał Miłecki wrote:
>>
>> After spotting a lot of N-PHY-similar functions in
>> BCM4331 dump of MMIO ops - split into names parts
>> I was able to finally improve HT-PHY code.
>>
>> It now sets TX basically, I can finally talk with devices that are few
>> meters away, not just few centimetres. It's a little patch bomb, sorry
>> for that, but I wasn't sure if my code is correct until it was complete
>> and started working.
>>
>> Rafał Miłecki (13):
>> b43: HT-PHY: rename AFE defines
>> b43: HT-PHY: add classifier control function
>> b43: HT-PHY: move TX fix to the separated function
>> b43: HT-PHY: implement spurious tone avoidance
>> b43: HT-PHY: implement MAC reclocking
>> b43: HT-PHY: implement CCA reset
>> b43: HT-PHY: implement PA override
>> b43: HT-PHY: implement controlling TX power control
>> b43: HT-PHY: implement stopping sample tone playback
>> b43: HT-PHY: implement playing sample tone
>> b43: HT-PHY: implement RSSI polling
>> b43: HT-PHY: setup TX power control
>> b43: HT-PHY: enable basic TX power setup
>>
>> drivers/net/wireless/b43/phy_ht.c | 603
>> +++++++++++++++++++++++++++++++++----
>> drivers/net/wireless/b43/phy_ht.h | 77 ++++-
>> 2 files changed, 613 insertions(+), 67 deletions(-)
>
>
> What tree is used for these patches? Numbers 1-7 applied with offsets, and
> some fuzz. Number 8 failed, and I quit trying there. I am using
> wireless-testing that was a fresh pull yesterday after John rebased it.

Whoops? It should apply just fine on re-based wireless-testing. I
think I've refreshed my tree today.

git log drivers/net/wireless/

commit 7f6231751ef492c38dbef61d14881bff6f1de165
Author: Rafał Miłecki <[email protected]>
Date: Sun Feb 24 17:41:56 2013 +0100

b43: HT-PHY: rename AFE defines

commit 7c2332b8061b7d4d7cd539ced1277e78d976f3da
Author: Rafał Miłecki <[email protected]>
Date: Mon Mar 4 16:39:10 2013 +0100

b43: HT-PHY: make it BCMA-only

So the newest b43 patch my patchset applies on top of is
7c2332b8061b7d4d7cd539ced1277e78d976f3da

--
Rafał

2013-03-07 19:01:05

by Larry Finger

[permalink] [raw]
Subject: Re: [PATCH 00/13] b43: implement basic TX power mgmt

On 03/07/2013 12:55 PM, Rafał Miłecki wrote:
> 2013/3/7 Larry Finger <[email protected]>:
>> On 03/07/2013 09:47 AM, Rafał Miłecki wrote:
>>>
>>> After spotting a lot of N-PHY-similar functions in
>>> BCM4331 dump of MMIO ops - split into names parts
>>> I was able to finally improve HT-PHY code.
>>>
>>> It now sets TX basically, I can finally talk with devices that are few
>>> meters away, not just few centimetres. It's a little patch bomb, sorry
>>> for that, but I wasn't sure if my code is correct until it was complete
>>> and started working.
>>>
>>> Rafał Miłecki (13):
>>> b43: HT-PHY: rename AFE defines
>>> b43: HT-PHY: add classifier control function
>>> b43: HT-PHY: move TX fix to the separated function
>>> b43: HT-PHY: implement spurious tone avoidance
>>> b43: HT-PHY: implement MAC reclocking
>>> b43: HT-PHY: implement CCA reset
>>> b43: HT-PHY: implement PA override
>>> b43: HT-PHY: implement controlling TX power control
>>> b43: HT-PHY: implement stopping sample tone playback
>>> b43: HT-PHY: implement playing sample tone
>>> b43: HT-PHY: implement RSSI polling
>>> b43: HT-PHY: setup TX power control
>>> b43: HT-PHY: enable basic TX power setup
>>>
>>> drivers/net/wireless/b43/phy_ht.c | 603
>>> +++++++++++++++++++++++++++++++++----
>>> drivers/net/wireless/b43/phy_ht.h | 77 ++++-
>>> 2 files changed, 613 insertions(+), 67 deletions(-)
>>
>>
>> What tree is used for these patches? Numbers 1-7 applied with offsets, and
>> some fuzz. Number 8 failed, and I quit trying there. I am using
>> wireless-testing that was a fresh pull yesterday after John rebased it.
>
> I've just checkouted origin/master again, to make sure everything is
> clean, and patches applied fine. Please make sure you're using latest
> wireless-testing like a
> http://git.kernel.org/cgit/linux/kernel/git/linville/wireless-testing.git/commit/?id=12c18c7a3d8f20366424834b20be40f7f3a9e2c2

That is the tree that I have. I will explore more.

Larry



2013-03-09 11:59:43

by Hauke Mehrtens

[permalink] [raw]
Subject: Re: [PATCH 00/13] b43: implement basic TX power mgmt

On 03/09/2013 12:20 PM, Rafał Miłecki wrote:
> 2013/3/7 Larry Finger <[email protected]>:
>> On 03/07/2013 09:47 AM, Rafał Miłecki wrote:
>>>
>>> After spotting a lot of N-PHY-similar functions in
>>> BCM4331 dump of MMIO ops - split into names parts
>>> I was able to finally improve HT-PHY code.
>>>
>>> It now sets TX basically, I can finally talk with devices that are few
>>> meters away, not just few centimetres. It's a little patch bomb, sorry
>>> for that, but I wasn't sure if my code is correct until it was complete
>>> and started working.
>>>
>>> Rafał Miłecki (13):
>>> b43: HT-PHY: rename AFE defines
>>> b43: HT-PHY: add classifier control function
>>> b43: HT-PHY: move TX fix to the separated function
>>> b43: HT-PHY: implement spurious tone avoidance
>>> b43: HT-PHY: implement MAC reclocking
>>> b43: HT-PHY: implement CCA reset
>>> b43: HT-PHY: implement PA override
>>> b43: HT-PHY: implement controlling TX power control
>>> b43: HT-PHY: implement stopping sample tone playback
>>> b43: HT-PHY: implement playing sample tone
>>> b43: HT-PHY: implement RSSI polling
>>> b43: HT-PHY: setup TX power control
>>> b43: HT-PHY: enable basic TX power setup
>>>
>>> drivers/net/wireless/b43/phy_ht.c | 603
>>> +++++++++++++++++++++++++++++++++----
>>> drivers/net/wireless/b43/phy_ht.h | 77 ++++-
>>> 2 files changed, 613 insertions(+), 67 deletions(-)
>>
>>
>> What tree is used for these patches? Numbers 1-7 applied with offsets, and
>> some fuzz. Number 8 failed, and I quit trying there. I am using
>> wireless-testing that was a fresh pull yesterday after John rebased it.
>
> Has anyone else tried to apply this patchset?
>

I just applied them on wireless-testing/master without any problems,
last commit was 14c8aaa01066072600b13b9825c571e4ecf7c0e9
I haven't seen any fuzz or wrong offset warning.

Hauke

2013-03-07 15:47:47

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 03/13] b43: HT-PHY: move TX fix to the separated function

On N-PHY after B43_PHY_B_TEST operation there is a call to TX power fix
function which iterates over available cores. It matches our HT-PHY code
which means it's probably also some TX fix.

Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_ht.c | 46 ++++++++++++++++++++++---------------
1 file changed, 28 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 2a65d01..f7463aa 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -256,6 +256,32 @@ static void b43_phy_ht_bphy_init(struct b43_wldev *dev)
}

/**************************************************
+ * Tx/Rx
+ **************************************************/
+
+static void b43_phy_ht_tx_power_fix(struct b43_wldev *dev)
+{
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ u16 mask;
+ u32 tmp = b43_httab_read(dev, B43_HTTAB32(26, 0xE8));
+
+ if (0) /* FIXME */
+ mask = 0x2 << (i * 4);
+ else
+ mask = 0;
+ b43_phy_mask(dev, B43_PHY_EXTG(0x108), mask);
+
+ b43_httab_write(dev, B43_HTTAB16(7, 0x110 + i), tmp >> 16);
+ b43_httab_write(dev, B43_HTTAB8(13, 0x63 + (i * 4)),
+ tmp & 0xFF);
+ b43_httab_write(dev, B43_HTTAB8(13, 0x73 + (i * 4)),
+ tmp & 0xFF);
+ }
+}
+
+/**************************************************
* Channel switching ops.
**************************************************/

@@ -264,7 +290,6 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
struct ieee80211_channel *new_channel)
{
bool old_band_5ghz;
- u8 i;

old_band_5ghz = b43_phy_read(dev, B43_PHY_HT_BANDCTL) & 0; /* FIXME */
if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) {
@@ -290,23 +315,8 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
b43_phy_mask(dev, B43_PHY_HT_TEST, ~0x840);
}

- /* TODO: separated function? */
- for (i = 0; i < 3; i++) {
- u16 mask;
- u32 tmp = b43_httab_read(dev, B43_HTTAB32(26, 0xE8));
-
- if (0) /* FIXME */
- mask = 0x2 << (i * 4);
- else
- mask = 0;
- b43_phy_mask(dev, B43_PHY_EXTG(0x108), mask);
-
- b43_httab_write(dev, B43_HTTAB16(7, 0x110 + i), tmp >> 16);
- b43_httab_write(dev, B43_HTTAB8(13, 0x63 + (i * 4)),
- tmp & 0xFF);
- b43_httab_write(dev, B43_HTTAB8(13, 0x73 + (i * 4)),
- tmp & 0xFF);
- }
+ if (1) /* TODO: On N it's for early devices only, what about HT? */
+ b43_phy_ht_tx_power_fix(dev);

b43_phy_write(dev, 0x017e, 0x3830);
}
--
1.7.10.4


2013-03-09 12:52:21

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH V2 08/13] b43: HT-PHY: implement controlling TX power control

Don't enable it until we have (almost?) whole TX power management
figured out. It's similar to the N-PHY, the difference is that we call a
"fix" *before* disabling power control.

Signed-off-by: Rafał Miłecki <[email protected]>
---
V2: use static for cmd_regs array
---
drivers/net/wireless/b43/phy_ht.c | 55 +++++++++++++++++++++++++++++++++++++
drivers/net/wireless/b43/phy_ht.h | 13 +++++++++
2 files changed, 68 insertions(+)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index 1998dca..1663551 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -319,6 +319,46 @@ static void b43_phy_ht_tx_power_fix(struct b43_wldev *dev)
}
}

+#if 0
+static void b43_phy_ht_tx_power_ctl(struct b43_wldev *dev, bool enable)
+{
+ struct b43_phy_ht *phy_ht = dev->phy.ht;
+ u16 en_bits = B43_PHY_HT_TXPCTL_CMD_C1_COEFF |
+ B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN |
+ B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN;
+ static const u16 cmd_regs[3] = { B43_PHY_HT_TXPCTL_CMD_C1,
+ B43_PHY_HT_TXPCTL_CMD_C2,
+ B43_PHY_HT_TXPCTL_CMD_C3 };
+ int i;
+
+ if (!enable) {
+ if (b43_phy_read(dev, B43_PHY_HT_TXPCTL_CMD_C1) & en_bits) {
+ /* We disable enabled TX pwr ctl, save it's state */
+ /*
+ * TODO: find the registers. On N-PHY they were 0x1ed
+ * and 0x1ee, we need 3 such a registers for HT-PHY
+ */
+ }
+ b43_phy_mask(dev, B43_PHY_HT_TXPCTL_CMD_C1, ~en_bits);
+ } else {
+ b43_phy_set(dev, B43_PHY_HT_TXPCTL_CMD_C1, en_bits);
+
+ if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
+ for (i = 0; i < 3; i++)
+ b43_phy_write(dev, cmd_regs[i], 0x32);
+ }
+
+ for (i = 0; i < 3; i++)
+ if (phy_ht->tx_pwr_idx[i] <=
+ B43_PHY_HT_TXPCTL_CMD_C1_INIT)
+ b43_phy_write(dev, cmd_regs[i],
+ phy_ht->tx_pwr_idx[i]);
+ }
+
+ phy_ht->tx_pwr_ctl = enable;
+}
+#endif
+
/**************************************************
* Channel switching ops.
**************************************************/
@@ -455,14 +495,21 @@ static void b43_phy_ht_op_prepare_structs(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
struct b43_phy_ht *phy_ht = phy->ht;
+ int i;

memset(phy_ht, 0, sizeof(*phy_ht));
+
+ phy_ht->tx_pwr_ctl = true;
+ for (i = 0; i < 3; i++)
+ phy_ht->tx_pwr_idx[i] = B43_PHY_HT_TXPCTL_CMD_C1_INIT + 1;
}

static int b43_phy_ht_op_init(struct b43_wldev *dev)
{
+ struct b43_phy_ht *phy_ht = dev->phy.ht;
u16 tmp;
u16 clip_state[3];
+ bool saved_tx_pwr_ctl;

if (dev->dev->bus_type != B43_BUS_BCMA) {
b43err(dev->wl, "HT-PHY is supported only on BCMA bus!\n");
@@ -589,6 +636,14 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
b43_httab_write_bulk(dev, B43_HTTAB32(0x1a, 0xc0),
B43_HTTAB_1A_C0_LATE_SIZE, b43_httab_0x1a_0xc0_late);

+ saved_tx_pwr_ctl = phy_ht->tx_pwr_ctl;
+ b43_phy_ht_tx_power_fix(dev);
+#if 0
+ b43_phy_ht_tx_power_ctl(dev, false);
+ /* TODO */
+ b43_phy_ht_tx_power_ctl(dev, saved_tx_pwr_ctl);
+#endif
+
return 0;
}

diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index 684807c..bc7a43f 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -22,6 +22,13 @@
#define B43_PHY_HT_BW4 0x1D1
#define B43_PHY_HT_BW5 0x1D2
#define B43_PHY_HT_BW6 0x1D3
+#define B43_PHY_HT_TXPCTL_CMD_C1 0x1E7 /* TX power control command */
+#define B43_PHY_HT_TXPCTL_CMD_C1_INIT 0x007F /* Init */
+#define B43_PHY_HT_TXPCTL_CMD_C1_COEFF 0x2000 /* Power control coefficients */
+#define B43_PHY_HT_TXPCTL_CMD_C1_HWPCTLEN 0x4000 /* Hardware TX power control enable */
+#define B43_PHY_HT_TXPCTL_CMD_C1_PCTLEN 0x8000 /* TX power control enable */
+#define B43_PHY_HT_TXPCTL_CMD_C2 0x222
+#define B43_PHY_HT_TXPCTL_CMD_C2_INIT 0x007F

#define B43_PHY_HT_C1_CLIP1THRES B43_PHY_OFDM(0x00E)
#define B43_PHY_HT_C2_CLIP1THRES B43_PHY_OFDM(0x04E)
@@ -51,6 +58,9 @@
#define B43_PHY_HT_AFE_C3_OVER B43_PHY_EXTG(0x118)
#define B43_PHY_HT_AFE_C3 B43_PHY_EXTG(0x119)

+#define B43_PHY_HT_TXPCTL_CMD_C3 B43_PHY_EXTG(0x164)
+#define B43_PHY_HT_TXPCTL_CMD_C3_INIT 0x007F
+
#define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A)


@@ -67,6 +77,9 @@ struct b43_phy_ht_channeltab_e_phy {

struct b43_phy_ht {
u16 rf_ctl_int_save[3];
+
+ bool tx_pwr_ctl;
+ u8 tx_pwr_idx[3];
};


--
1.7.10.4


2013-03-09 11:20:27

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 00/13] b43: implement basic TX power mgmt

2013/3/7 Larry Finger <[email protected]>:
> On 03/07/2013 09:47 AM, Rafał Miłecki wrote:
>>
>> After spotting a lot of N-PHY-similar functions in
>> BCM4331 dump of MMIO ops - split into names parts
>> I was able to finally improve HT-PHY code.
>>
>> It now sets TX basically, I can finally talk with devices that are few
>> meters away, not just few centimetres. It's a little patch bomb, sorry
>> for that, but I wasn't sure if my code is correct until it was complete
>> and started working.
>>
>> Rafał Miłecki (13):
>> b43: HT-PHY: rename AFE defines
>> b43: HT-PHY: add classifier control function
>> b43: HT-PHY: move TX fix to the separated function
>> b43: HT-PHY: implement spurious tone avoidance
>> b43: HT-PHY: implement MAC reclocking
>> b43: HT-PHY: implement CCA reset
>> b43: HT-PHY: implement PA override
>> b43: HT-PHY: implement controlling TX power control
>> b43: HT-PHY: implement stopping sample tone playback
>> b43: HT-PHY: implement playing sample tone
>> b43: HT-PHY: implement RSSI polling
>> b43: HT-PHY: setup TX power control
>> b43: HT-PHY: enable basic TX power setup
>>
>> drivers/net/wireless/b43/phy_ht.c | 603
>> +++++++++++++++++++++++++++++++++----
>> drivers/net/wireless/b43/phy_ht.h | 77 ++++-
>> 2 files changed, 613 insertions(+), 67 deletions(-)
>
>
> What tree is used for these patches? Numbers 1-7 applied with offsets, and
> some fuzz. Number 8 failed, and I quit trying there. I am using
> wireless-testing that was a fresh pull yesterday after John rebased it.

Has anyone else tried to apply this patchset?

--
Rafał

2013-03-07 18:09:30

by Larry Finger

[permalink] [raw]
Subject: Re: [PATCH 00/13] b43: implement basic TX power mgmt

On 03/07/2013 09:47 AM, Rafał Miłecki wrote:
> After spotting a lot of N-PHY-similar functions in
> BCM4331 dump of MMIO ops - split into names parts
> I was able to finally improve HT-PHY code.
>
> It now sets TX basically, I can finally talk with devices that are few
> meters away, not just few centimetres. It's a little patch bomb, sorry
> for that, but I wasn't sure if my code is correct until it was complete
> and started working.
>
> Rafał Miłecki (13):
> b43: HT-PHY: rename AFE defines
> b43: HT-PHY: add classifier control function
> b43: HT-PHY: move TX fix to the separated function
> b43: HT-PHY: implement spurious tone avoidance
> b43: HT-PHY: implement MAC reclocking
> b43: HT-PHY: implement CCA reset
> b43: HT-PHY: implement PA override
> b43: HT-PHY: implement controlling TX power control
> b43: HT-PHY: implement stopping sample tone playback
> b43: HT-PHY: implement playing sample tone
> b43: HT-PHY: implement RSSI polling
> b43: HT-PHY: setup TX power control
> b43: HT-PHY: enable basic TX power setup
>
> drivers/net/wireless/b43/phy_ht.c | 603 +++++++++++++++++++++++++++++++++----
> drivers/net/wireless/b43/phy_ht.h | 77 ++++-
> 2 files changed, 613 insertions(+), 67 deletions(-)

What tree is used for these patches? Numbers 1-7 applied with offsets, and some
fuzz. Number 8 failed, and I quit trying there. I am using wireless-testing that
was a fresh pull yesterday after John rebased it.

Larry



2013-03-07 15:47:56

by Rafał Miłecki

[permalink] [raw]
Subject: [PATCH 07/13] b43: HT-PHY: implement PA override


Signed-off-by: Rafał Miłecki <[email protected]>
---
drivers/net/wireless/b43/phy_ht.c | 22 ++++++++++++++++++++++
drivers/net/wireless/b43/phy_ht.h | 5 +++++
2 files changed, 27 insertions(+)

diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index aedbae7..3b3517c 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -178,6 +178,26 @@ static void b43_phy_ht_force_rf_sequence(struct b43_wldev *dev, u16 rf_seq)
b43_phy_write(dev, B43_PHY_HT_RF_SEQ_MODE, save_seq_mode);
}

+static void b43_phy_ht_pa_override(struct b43_wldev *dev, bool enable)
+{
+ struct b43_phy_ht *htphy = dev->phy.ht;
+ const u16 regs[3] = { B43_PHY_HT_RF_CTL_INT_C1,
+ B43_PHY_HT_RF_CTL_INT_C2,
+ B43_PHY_HT_RF_CTL_INT_C3 };
+ int i;
+
+ if (enable) {
+ for (i = 0; i < 3; i++)
+ b43_phy_write(dev, regs[i], htphy->rf_ctl_int_save[i]);
+ } else {
+ for (i = 0; i < 3; i++)
+ htphy->rf_ctl_int_save[i] = b43_phy_read(dev, regs[i]);
+ /* TODO: Does 5GHz band use different value (not 0x0400)? */
+ for (i = 0; i < 3; i++)
+ b43_phy_write(dev, regs[i], 0x0400);
+ }
+}
+
/**************************************************
* Various PHY ops
**************************************************/
@@ -554,8 +574,10 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)

b43_mac_phy_clock_set(dev, true);

+ b43_phy_ht_pa_override(dev, false);
b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RX2TX);
b43_phy_ht_force_rf_sequence(dev, B43_PHY_HT_RF_SEQ_TRIG_RST2RX);
+ b43_phy_ht_pa_override(dev, true);

/* TODO: Should we restore it? Or store it in global PHY info? */
b43_phy_ht_classifier(dev, 0, 0);
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index 52603af..684807c 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -40,6 +40,10 @@

#define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010)

+#define B43_PHY_HT_RF_CTL_INT_C1 B43_PHY_EXTG(0x04c)
+#define B43_PHY_HT_RF_CTL_INT_C2 B43_PHY_EXTG(0x06c)
+#define B43_PHY_HT_RF_CTL_INT_C3 B43_PHY_EXTG(0x08c)
+
#define B43_PHY_HT_AFE_C1_OVER B43_PHY_EXTG(0x110)
#define B43_PHY_HT_AFE_C1 B43_PHY_EXTG(0x111)
#define B43_PHY_HT_AFE_C2_OVER B43_PHY_EXTG(0x114)
@@ -62,6 +66,7 @@ struct b43_phy_ht_channeltab_e_phy {


struct b43_phy_ht {
+ u16 rf_ctl_int_save[3];
};


--
1.7.10.4


2013-03-09 12:58:24

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 00/13] b43: implement basic TX power mgmt

2013/3/7 Rafał Miłecki <[email protected]>:
> After spotting a lot of N-PHY-similar functions in
> BCM4331 dump of MMIO ops - split into names parts
> I was able to finally improve HT-PHY code.
>
> It now sets TX basically, I can finally talk with devices that are few
> meters away, not just few centimetres. It's a little patch bomb, sorry
> for that, but I wasn't sure if my code is correct until it was complete
> and started working.
>
> Rafał Miłecki (13):
> b43: HT-PHY: rename AFE defines
> b43: HT-PHY: add classifier control function
> b43: HT-PHY: move TX fix to the separated function
> b43: HT-PHY: implement spurious tone avoidance
> b43: HT-PHY: implement MAC reclocking
> b43: HT-PHY: implement CCA reset
> b43: HT-PHY: implement PA override
> b43: HT-PHY: implement controlling TX power control
> b43: HT-PHY: implement stopping sample tone playback
> b43: HT-PHY: implement playing sample tone
> b43: HT-PHY: implement RSSI polling
> b43: HT-PHY: setup TX power control
> b43: HT-PHY: enable basic TX power setup

I've finished sending V2 of some patches, arrays are now converted to
static const where possible.

I've tried applying this 3 times and Hauke confirmed is applies
cleanly, so I hope it's fine now.

--
Rafał

2013-03-13 23:19:09

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 00/13] b43: implement basic TX power mgmt

2013/3/13 David Woodhouse <[email protected]>:
> On Thu, 2013-03-07 at 16:47 +0100, Rafał Miłecki wrote:
>> After spotting a lot of N-PHY-similar functions in
>> BCM4331 dump of MMIO ops - split into names parts
>> I was able to finally improve HT-PHY code.
>>
>> It now sets TX basically, I can finally talk with devices that are few
>> meters away, not just few centimetres. It's a little patch bomb, sorry
>> for that, but I wasn't sure if my code is correct until it was complete
>> and started working.
>
> If you have a git tree I can pull this from, I'd be happy to give it
> some testing...

You can try wireless-testing:
http://git.kernel.org/cgit/linux/kernel/git/linville/wireless-testing.git

--
Rafał

2013-03-16 13:50:22

by Rafał Miłecki

[permalink] [raw]
Subject: Re: [PATCH 00/13] b43: implement basic TX power mgmt

2013/3/14 David Woodhouse <[email protected]>:
> On Thu, 2013-03-14 at 00:19 +0100, Rafał Miłecki wrote:
>>
>> > If you have a git tree I can pull this from, I'd be happy to give it
>> > some testing...
>>
>> You can try wireless-testing:
>> http://git.kernel.org/cgit/linux/kernel/git/linville/wireless-testing.git
>
> Thanks. This is not an improvement here.
>
> Sitting at my desk, about 5m from my WNDR3800 access point with walls
> and chimney in between them, I was previously seeing a TX rate of 48Mb/s
> up to 54Mb/s (reported by 'iwconfig wlan0' and also as the RX rate for
> the corresponding wireless client in OpenWRT's status page).
>
> A primitive test copying a 143MiB file to a wired host would take 35
> seconds, averaging 4.1MiB/s.
>
> With these changes I get TX rates of about 18-24Mb/s and copying the
> same file takes 82 seconds, averaging 1.7MiB/s

I was thinking about this and analyzing dump a bit more. My theory
(that makes the most sense for me) is that:
1) Cards differ by default TX configuration. Your default
configuration works pretty well in your environment (32.8Mib/s? that's
really nice!). My card is probably different and in default
configuration can barely transmit anything).
2) With the recent changes we put cards in some semi-optimal configuration
3) To achieve full performance we still have to implement dynamic TX
power management

In your case... well it probably was better to don't touch TX power at
all ;) Unfortunately it has to be finally implemented, to allow all
cards work with some acceptable performance.


> That's comparing the Fedora 3.8.2-206.fc18.x86_64 kernel with current
> wireless-testing, rather than wireless-testing from before and after
> your changes. But that shouldn't matter, presumably?
>
> Do you want me to do some more specific tests?

To verify my theory, could you try reverting
4969b41798e512689bba57c8c44d873216eba814, AKA
b43: HT-PHY: enable basic TX power setup
? Does reverting this patch brings you back ~4.1MiB/s?

If it doesn't, could you bisect? Two another patches I would suspect;
b43: HT-PHY: implement spurious tone avoidance
b43: HT-PHY: implement MAC reclocking

--
Rafał

2013-03-09 17:21:39

by Larry Finger

[permalink] [raw]
Subject: Re: [PATCH 00/13] b43: implement basic TX power mgmt

On 03/09/2013 06:58 AM, Rafał Miłecki wrote:
> I've finished sending V2 of some patches, arrays are now converted to
> static const where possible.
>
> I've tried applying this 3 times and Hauke confirmed is applies
> cleanly, so I hope it's fine now.

I do not know what happened earlier, but the using the latest set, everything
applied cleanly.

Now for some testing.

Larry