From: Andreas Wendleder <gonsolo@gmail.com>
To: linux-wireless@vger.kernel.org
Cc: Johannes Berg <johannes@sipsolutions.net>,
b43-dev@lists.infradead.org, Michael Buesch <m@bues.ch>,
Alessio Ferri <alessio.ferri@mythread.it>,
kvalo@kernel.org, julian.calaby@gmail.com, jpeisach@ubuntu.com,
rosenp@gmail.com, linux-kernel@vger.kernel.org
Subject: [PATCH RFC wireless-next 2/3] wifi: b43: MAC core setup for core revisions 40 and 42
Date: Thu, 12 Nov 2026 18:56:23 +0100 [thread overview]
Message-ID: <20261112175624.40547-3-gonsolo@gmail.com> (raw)
In-Reply-To: <20261112175624.40547-1-gonsolo@gmail.com>
The core revisions 40 and 42 of the BCM4352 and BCM4360 need these
differences from the older cores:
- PHY reset: the reset is asserted with the clock forced and released
with the clock free, in the order the vendor driver uses.
- GPIOs: the pins are host driven with GPIO1 and GPIO2 high. This is the
pattern of the MacBookAir6,1 (front end control); other boards may
need other values.
- The template and TX FIFOs are carved out of the MAC memory and the TX
queue table is set up, because the microcode does not size them.
- MACCTL is written without SHM_ENABLED, which the vendor driver never
sets on this core.
- The RX interrupt lazy timeout (register 0x100) is set so that an
interrupt is raised after every frame.
The microcode (revision 784 and above, b43_ucode_is_ac()) has no key
table pointer at the legacy KTP word, it reads 0, so b43_security_init()
must not clear the "key table": that zeroed SHM 0x000-0x3a0 (rate maps,
ACK/CTS PHY control, microcode state) on every core init.
b43_op_set_key() returns -EOPNOTSUPP, mac80211 does the crypto in
software.
Signed-off-by: Andreas Wendleder <gonsolo@gmail.com>
---
drivers/net/wireless/broadcom/b43/b43.h | 8 ++
drivers/net/wireless/broadcom/b43/main.c | 101 ++++++++++++++++++++++-
2 files changed, 108 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/broadcom/b43/b43.h b/drivers/net/wireless/broadcom/b43/b43.h
index 80b299b..92227ff 100644
--- a/drivers/net/wireless/broadcom/b43/b43.h
+++ b/drivers/net/wireless/broadcom/b43/b43.h
@@ -1030,6 +1030,14 @@ static inline void b43_device_disable(struct b43_wldev *wldev,
wldev->dev->device_disable(wldev->dev, core_specific_flags);
}
+/* Microcode of the AC cores (revisions 784, 832 and 928). Valid once the
+ * microcode is loaded; only revision 832 has been tested.
+ */
+static inline bool b43_ucode_is_ac(struct b43_wldev *dev)
+{
+ return dev->fw.rev >= 784;
+}
+
static inline u16 b43_read16(struct b43_wldev *dev, u16 offset)
{
return dev->dev->read16(dev->dev, offset);
diff --git a/drivers/net/wireless/broadcom/b43/main.c b/drivers/net/wireless/broadcom/b43/main.c
index e2e8ca0..205d429 100644
--- a/drivers/net/wireless/broadcom/b43/main.c
+++ b/drivers/net/wireless/broadcom/b43/main.c
@@ -1235,6 +1235,24 @@ static void b43_bcma_phy_reset(struct b43_wldev *dev)
{
u32 flags;
+ if (b43_is_ac_core(dev)) {
+ flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
+ flags |= B43_BCMA_IOCTL_PHY_RESET |
+ B43_BCMA_IOCTL_PHY_BW_20MHZ | BCMA_IOCTL_FGC |
+ B43_BCMA_IOCTL_PHY_CLKEN;
+ bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags);
+ udelay(2);
+ bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags);
+ flags &= ~(B43_BCMA_IOCTL_PHY_RESET | BCMA_IOCTL_FGC |
+ B43_BCMA_IOCTL_PHY_CLKEN);
+ bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags);
+ udelay(1);
+ flags |= B43_BCMA_IOCTL_PHY_CLKEN;
+ bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, flags);
+ udelay(1);
+ return;
+ }
+
/* Put PHY into reset */
flags = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
flags |= B43_BCMA_IOCTL_PHY_RESET;
@@ -2914,6 +2932,18 @@ static int b43_gpio_init(struct b43_wldev *dev)
switch (dev->dev->bus_type) {
#ifdef CONFIG_B43_BCMA
case B43_BUS_BCMA:
+ if (b43_is_ac_core(dev)) {
+ struct bcma_drv_cc *cc = &dev->dev->bdev->bus->drv_cc;
+
+ /*
+ * the vendor driver keeps the pins host-driven with
+ * GPIO1+2 high (front-end control on MacBookAir6,1).
+ */
+ bcma_chipco_gpio_control(cc, mask | 0xa7, 0);
+ bcma_chipco_gpio_out(cc, 0xa7, 0x06);
+ bcma_chipco_gpio_outen(cc, 0xa7, 0xa7);
+ break;
+ }
bcma_chipco_gpio_control(&dev->dev->bdev->bus->drv_cc, mask, set);
break;
#endif
@@ -3245,6 +3275,53 @@ static void b43_chip_exit(struct b43_wldev *dev)
/* Initialize the chip
* https://bcm-specs.sipsolutions.net/ChipInit
*/
+/*
+ * rev 40+ MAC: carve template/TX FIFOs out of MAC memory and set up the TX
+ * queue table (as the vendor driver does it).
+ */
+
+static void b43_ac_fifo_init(struct b43_wldev *dev)
+{
+ static const u8 fifos[] = { 7, 0, 1, 2, 3, 4, 5 };
+ u16 total = (b43_read32(dev, 0x15c) >> 1) & 0xffc;
+ const u16 tpl = 0x2a, fifo_sz = 0x20, blk = 0xb;
+ unsigned int i;
+ int t;
+
+ b43_write16(dev, 0x542, total);
+ b43_write16(dev, 0x540, 5);
+ for (t = 0; t < 20 && (b43_read16(dev, 0x540) & 1); t++)
+ udelay(10);
+ for (i = 0; i < ARRAY_SIZE(fifos); i++) {
+ if (fifos[i] == 7) {
+ b43_write16(dev, 0x54a, tpl);
+ b43_write16(dev, 0x54c, tpl);
+ b43_write16(dev, 0x520, tpl);
+ b43_write16(dev, 0x54e, ((tpl - 4) << 8) | tpl);
+ } else {
+ b43_write16(dev, 0x54a, total - tpl);
+ b43_write16(dev, 0x54c, fifo_sz);
+ b43_write16(dev, 0x520, blk);
+ b43_write16(dev, 0x54e,
+ ((blk * 2 - 4) << 8) | (blk * 2));
+ }
+ b43_write16(dev, 0x550, 0x740c);
+ b43_write16(dev, 0x548, fifos[i] | 0x10);
+ }
+ for (i = 0; i < 0x2a; i++) {
+ u16 end = min_t(u16, i + 2, 0x29);
+
+ b43_write16(dev, 0x534, i);
+ b43_write16(dev, 0x536, end);
+ b43_write16(dev, 0x532, end + 1 - i);
+ b43_write16(dev, 0x530, (i << 4) | 0x8007);
+ for (t = 0; t < 20 && b43_read16(dev, 0x530); t++)
+ udelay(10);
+ }
+ b43dbg(dev->wl, "AC FIFO init: total %#x, 0x540=%04x 0x530=%04x\n",
+ total, b43_read16(dev, 0x540), b43_read16(dev, 0x530));
+}
+
static int b43_chip_init(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
@@ -3253,7 +3330,10 @@ static int b43_chip_init(struct b43_wldev *dev)
u16 value16;
/* Initialize the MAC control */
- macctl = B43_MACCTL_IHR_ENABLED | B43_MACCTL_SHM_ENABLED;
+ macctl = B43_MACCTL_IHR_ENABLED;
+ /* The vendor driver never sets SHM_ENABLED on AC-PHY cores. */
+ if (!b43_is_ac_core(dev))
+ macctl |= B43_MACCTL_SHM_ENABLED;
if (dev->phy.gmode)
macctl |= B43_MACCTL_GMODE;
macctl |= B43_MACCTL_INFRA;
@@ -3275,6 +3355,9 @@ static int b43_chip_init(struct b43_wldev *dev)
if (err)
goto err_gpio_clean;
+ if (b43_is_ac_core(dev))
+ b43_ac_fifo_init(dev);
+
/* Turn the Analog on and initialize the PHY. */
phy->ops->switch_analog(dev, 1);
err = b43_phy_init(dev);
@@ -3325,6 +3408,10 @@ static int b43_chip_init(struct b43_wldev *dev)
b43_write32(dev, B43_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
b43_write32(dev, B43_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
b43_write32(dev, B43_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
+ if (b43_is_ac_core(dev)) {
+ /* intrcvlazy0: raise the RX interrupt after every frame. */
+ b43_write32(dev, 0x100, 1 << 24);
+ }
b43_mac_phy_clock_set(dev, true);
@@ -3529,6 +3616,15 @@ error:
static void b43_security_init(struct b43_wldev *dev)
{
+ /*
+ * rev 40+ (AC) ucode has no key table pointer at the legacy KTP word:
+ * it reads 0 there, so clearing the "key table" zeroed SHM 0x000-0x3a0
+ * (rate maps, ACK/CTS PHY control, ucode state) on every core init. AC
+ * has no hardware crypto support yet, so leave the key memory alone.
+ */
+ if (b43_ucode_is_ac(dev))
+ return;
+
dev->ktp = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_KTP);
/* KTP is a word address, but we address SHM bytewise.
* So multiply by two.
@@ -4178,6 +4274,9 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
if (modparam_nohwcrypt)
return -ENOSPC; /* User disabled HW-crypto */
+ if (b43_ucode_is_ac(wl->current_dev))
+ /* no AC key table yet, see b43_security_init */
+ return -EOPNOTSUPP;
if ((vif->type == NL80211_IFTYPE_ADHOC ||
vif->type == NL80211_IFTYPE_MESH_POINT) &&
next prev parent reply other threads:[~2026-11-12 17:56 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-12 17:56 [PATCH RFC wireless-next 0/3] wifi: b43: core revision 40 and 42 MAC setup (series 2/4) Andreas Wendleder
2026-11-12 17:56 ` [PATCH RFC wireless-next 1/3] wifi: b43: set the DMA burst and prefetch bits of core revisions 40 and 42 Andreas Wendleder
2026-11-12 17:56 ` Andreas Wendleder [this message]
2026-11-12 17:56 ` [PATCH RFC wireless-next 3/3] wifi: b43: address match table, templates and beacons for the AC microcode Andreas Wendleder
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261112175624.40547-3-gonsolo@gmail.com \
--to=gonsolo@gmail.com \
--cc=alessio.ferri@mythread.it \
--cc=b43-dev@lists.infradead.org \
--cc=johannes@sipsolutions.net \
--cc=jpeisach@ubuntu.com \
--cc=julian.calaby@gmail.com \
--cc=kvalo@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-wireless@vger.kernel.org \
--cc=m@bues.ch \
--cc=rosenp@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®