Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH wireless] wifi: b43: fix 2.4 GHz reception on HT-PHY
@ 2026-10-19  2:24 Rosen Penev
  0 siblings, 0 replies; only message in thread
From: Rosen Penev @ 2026-10-19  2:24 UTC (permalink / raw)
  To: linux-wireless
  Cc: John W. Linville, Rafał Miłecki,
	open list:B43 WIRELESS DRIVER, open list

On a BCM4331 (HT-PHY rev 1, radio 2059 rev 0) b43 barely receives in
the 2.4 GHz band, with or without HT: against an access point half a
metre away, 15-45% of the pings are lost and iperf3 runs at 0-3
Mbit/s each way. The 5 GHz band works.

An mmiotrace of wl 6.30.223.271 on the same card shows two things b43
does not do:

- wl writes PHY table 9, 48 entries, on every PHY init in both bands.
  b43 never writes it.
- wl writes the RX gain tables 0, 1 and 40 (one per core) and the gain
  code tables 2, 3 and 41 on every band change, with different values
  for 2.4 and 5 GHz. b43 only writes entries 8-11 of tables 0, 1 and
  40, once at init, with values that are neither.

Write table 9 at PHY init and the gain tables on every channel setup,
with wl's values for the band. Replaying wl's state on the card showed
that table 9 is needed for any reception at all, and the gain tables
for full throughput. This also answers the old question of whether wl
meant table 2 instead of 40: table 40 is the gain table of core 3.

With an RT-N16 access point on channel 6 without HT, iperf3 now runs
at 15 Mbit/s each way, and 2 of 40 pings sent right after association
are lost.

Fixes: 98f8dc72ac50 ("b43: HT-PHY: init: add missing small-tables writes")
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
 drivers/net/wireless/broadcom/b43/phy_ht.c    | 62 ++++++++++++++++---
 .../net/wireless/broadcom/b43/tables_phy_ht.c | 11 ++++
 2 files changed, 65 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/broadcom/b43/phy_ht.c b/drivers/net/wireless/broadcom/b43/phy_ht.c
index fab8399c64f7..b6c200cba715 100644
--- a/drivers/net/wireless/broadcom/b43/phy_ht.c
+++ b/drivers/net/wireless/broadcom/b43/phy_ht.c
@@ -760,6 +760,58 @@ static void b43_phy_ht_spur_avoid(struct b43_wldev *dev,
 	b43_phy_ht_reset_cca(dev);
 }
 
+/*
+ * The RX gain tables depend on the band. Tables 0, 1 and 40 hold the gains
+ * of cores 1, 2 and 3, tables 2, 3 and 41 the matching gain codes. Values
+ * from wl, which writes them on every band change.
+ */
+static void b43_phy_ht_gain_tables(struct b43_wldev *dev,
+				   enum nl80211_band band)
+{
+	static const u8 gain_tbl[] = { 0, 1, 40 };
+	static const u8 code_tbl[] = { 2, 3, 41 };
+	static const u16 gain[2][4][4] = {
+		{ { 0x10, 0x10 }, { 0x0b, 0x11, 0x15, 0x1a },
+		  { 0xfd, 0x07, 0x07, 0x07 } },
+		{ { 0x0d, 0x0d }, { 0x0e, 0x14, 0x18, 0x1c },
+		  { 0xff, 0x07, 0x0b, 0x0b } },
+	};
+	static const u16 code[2][4] = {
+		{ 0, 1, 1, 1 }, { 0, 1, 2, 2 },
+	};
+	bool ghz5 = band == NL80211_BAND_5GHZ;
+	int core, i;
+
+	for (core = 0; core < ARRAY_SIZE(gain_tbl); core++) {
+		u8 g = gain_tbl[core], c = code_tbl[core];
+
+		for (i = 0; i < 2; i++)
+			b43_httab_write(dev, B43_HTTAB16(g, i),
+					gain[ghz5][0][i]);
+		for (i = 0; i < 4; i++) {
+			b43_httab_write(dev, B43_HTTAB16(g, 0x08 + i),
+					gain[ghz5][1][i]);
+			b43_httab_write(dev, B43_HTTAB16(g, 0x10 + i),
+					gain[ghz5][2][i]);
+			b43_httab_write(dev, B43_HTTAB16(c, 0x10 + i),
+					code[ghz5][i]);
+		}
+		for (i = 0; i <= 0xa; i++) {
+			if (ghz5) {
+				b43_httab_write(dev, B43_HTTAB16(g, 0x20 + i),
+						i < 2 ? 0xfa : 0xfd);
+				b43_httab_write(dev, B43_HTTAB16(c, 0x20 + i),
+						i < 2 ? 1 : 2);
+			} else {
+				b43_httab_write(dev, B43_HTTAB16(g, 0x20 + i),
+						i < 0xa ? 0x00 : 0xfd);
+				b43_httab_write(dev, B43_HTTAB16(c, 0x20 + i),
+						i < 0xa ? 1 : 2);
+			}
+		}
+	}
+}
+
 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)
@@ -801,6 +853,8 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
 
 	b43_phy_ht_spur_avoid(dev, new_channel);
 
+	b43_phy_ht_gain_tables(dev, new_channel->band);
+
 	b43_phy_write(dev, 0x017e, 0x3830);
 }
 
@@ -946,14 +1000,6 @@ static int b43_phy_ht_op_init(struct b43_wldev *dev)
 	b43_phy_maskset(dev, B43_PHY_OFDM(0x0141), 0xff00, 0x46);
 	b43_phy_maskset(dev, 0x0283, 0xff00, 0x40);
 
-	b43_httab_write_few(dev, B43_HTTAB16(00, 0x8), 4,
-			    0x09, 0x0e, 0x13, 0x18);
-	b43_httab_write_few(dev, B43_HTTAB16(01, 0x8), 4,
-			    0x09, 0x0e, 0x13, 0x18);
-	/* TODO: Did wl mean 2 instead of 40? */
-	b43_httab_write_few(dev, B43_HTTAB16(40, 0x8), 4,
-			    0x09, 0x0e, 0x13, 0x18);
-
 	b43_phy_maskset(dev, B43_PHY_OFDM(0x24), 0x3f, 0xd);
 	b43_phy_maskset(dev, B43_PHY_OFDM(0x64), 0x3f, 0xd);
 	b43_phy_maskset(dev, B43_PHY_OFDM(0xa4), 0x3f, 0xd);
diff --git a/drivers/net/wireless/broadcom/b43/tables_phy_ht.c b/drivers/net/wireless/broadcom/b43/tables_phy_ht.c
index 1acf2df66e5e..7952584c0170 100644
--- a/drivers/net/wireless/broadcom/b43/tables_phy_ht.c
+++ b/drivers/net/wireless/broadcom/b43/tables_phy_ht.c
@@ -14,6 +14,16 @@
 #include "phy_common.h"
 #include "phy_ht.h"
 
+/* Written by wl on every PHY init; without it 2.4 GHz reception fails */
+static const u16 b43_httab_0x09[] = {
+	0x0000, 0x0000, 0x0002, 0x0000, 0x0001, 0x0001, 0x0003, 0x0001,
+	0x0000, 0x0000, 0x0002, 0x0000, 0x0001, 0x0001, 0x0003, 0x0001,
+	0x0000, 0x0000, 0x0002, 0x0000, 0x0001, 0x0001, 0x0003, 0x0001,
+	0x0000, 0x0000, 0x0002, 0x0000, 0x0001, 0x0001, 0x0003, 0x0001,
+	0x0000, 0x0000, 0x0002, 0x0000, 0x0001, 0x0001, 0x0003, 0x0001,
+	0x0000, 0x0000, 0x0002, 0x0000, 0x0001, 0x0001, 0x0003, 0x0001,
+};
+
 static const u16 b43_httab_0x12[] = {
 	0x0000, 0x0008, 0x000a, 0x0010, 0x0012, 0x0019,
 	0x001a, 0x001c, 0x0080, 0x0088, 0x008a, 0x0090,
@@ -796,6 +806,7 @@ void b43_phy_ht_tables_init(struct b43_wldev *dev)
 	BUILD_BUG_ON(ARRAY_SIZE(b43_httab_0x1a_0xc0_late) !=
 			B43_HTTAB_1A_C0_LATE_SIZE);
 
+	httab_upload(dev, B43_HTTAB16(0x09, 0), b43_httab_0x09);
 	httab_upload(dev, B43_HTTAB16(0x12, 0), b43_httab_0x12);
 	httab_upload(dev, B43_HTTAB16(0x27, 0), b43_httab_0x27);
 	httab_upload(dev, B43_HTTAB16(0x26, 0), b43_httab_0x26);
-- 
2.56.0


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-10-19  2:24 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-19  2:24 [PATCH wireless] wifi: b43: fix 2.4 GHz reception on HT-PHY Rosen Penev

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox