Devicetree
 help / color / mirror / Atom feed
* [PATCH 0/4] bcma: support SHIM-attached big-endian SoC backplanes (BCM6362)
@ 2026-05-29  0:05 Alessio Ferri
  2026-05-29  0:05 ` [PATCH 1/4] bcma: support driver specific quirks from soc pdata Alessio Ferri
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Alessio Ferri @ 2026-05-29  0:05 UTC (permalink / raw)
  To: Rafał Miłecki, Alessio Ferri, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Florian Fainelli
  Cc: linux-kernel, linux-wireless, devicetree

Some BMIPS xDSL SoCs (BCM6362) integrate a Broadcom 802.11 backplane that is reachable
through bcma but differs from the BCM47xx SoCs host_soc was written for:
the AXI backplane is big-endian on a big-endian CPU, and the cores bcma must gate
(ChipCommon, the 802.11 core, the SHIM core) expose no per-core DMP wrappers — clock
and reset live in a small SoC-level SHIM Control register instead.

Rather than describe these quirks as DT properties on the bcma node, the SoC-specific
configuration is delivered to host_soc via platform_data from a parent bridge driver. The
bcma DT node stays a plain "brcm,bus-axi" and all the 6362-specific knowledge lives in the
bridge driver. The standard brcm,bus-axi path is unchanged.

The series is:
  1/4  bcma: support driver specific quirks from soc pdata
  2/4  bcma: allow SHIM-style mini-EROM wrapper-less cores in scan
  3/4  dt-bindings: bus: add brcm,bcm6362-wlan
  4/4  bus: add BCM6362 on-chip WLAN SHIM bridge driver

Patches 1-2 touch drivers/bcma (wireless tree); patch 3 is a new drivers/bus driver; patch 4 is
the binding. The patches are sent together to keep the whole context intact.

The original Broadcom driver materialized a fake PCI device, i don't think that would be allowed
in the kernel.

Tested on a D-Link DSL-3580L (BCM6362, d11 corerev 22, N-PHY):
- SHIM brings the backplane up,
- bcma enumerates ChipCommon + the 802.11 core,
- b43 binds.

b43 patches are necessary for the last point, but those has
already been sent in linux-wireless.

Assisted-by: Claude:claude-4.8-opus
Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>

---
Alessio Ferri (4):
      bcma: support driver specific quirks from soc pdata
      bcma: allow SHIM-style mini-EROM wrapper-less cores in scan
      dt-bindings: bus: add brcm,bcm6362-wlan
      bus: add BCM6362 on-chip WLAN SHIM bridge driver

 .../devicetree/bindings/bus/brcm,bcm6362-wlan.yaml | 106 +++++++++
 MAINTAINERS                                        |   7 +
 drivers/bcma/host_soc.c                            | 224 +++++++++++++++++-
 drivers/bcma/scan.c                                |  19 +-
 drivers/bus/Kconfig                                |  13 ++
 drivers/bus/Makefile                               |   1 +
 drivers/bus/bcm6362-wlan-shim.c                    | 252 +++++++++++++++++++++
 include/linux/bcma/bcma.h                          |  14 ++
 include/linux/platform_data/bcma_host_soc.h        |  31 +++
 9 files changed, 654 insertions(+), 13 deletions(-)
---
base-commit: 8fde5d1d47f69db6082dfa34500c27f8485389a5
change-id: 20260529-add-bcm6362-wlan-e3e72dbdeb8a

Best regards,
-- 
Alessio Ferri <alessio.ferri.3012@gmail.com>


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/4] bcma: support driver specific quirks from soc pdata
  2026-05-29  0:05 [PATCH 0/4] bcma: support SHIM-attached big-endian SoC backplanes (BCM6362) Alessio Ferri
@ 2026-05-29  0:05 ` Alessio Ferri
  2026-05-29  0:48   ` sashiko-bot
  2026-05-29  0:06 ` [PATCH 2/4] bcma: allow SHIM-style mini-EROM wrapper-less cores in scan Alessio Ferri
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 9+ messages in thread
From: Alessio Ferri @ 2026-05-29  0:05 UTC (permalink / raw)
  To: Rafał Miłecki, Alessio Ferri, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Florian Fainelli
  Cc: linux-kernel, linux-wireless, devicetree

Some BMIPS xDSL SoCs (BCM6362, BCM63268) integrate a Broadcom 802.11
backplane that is reachable through bcma but differs from the BCM47xx
SoCs the host_soc driver was originally written for in two ways:

  1. The AXI backplane sits on a big-endian peripheral bus on a
     big-endian CPU. readl()/writel() perform an asymmetric byte swap
     in this configuration and land each bit in the wrong position
     inside the peripheral;

  2. Per-core DMP wrappers (NMW/NSW != 0) do not exist for the cores
     that bcma needs to gate (ChipCommon, the 802.11 core, and the
     SHIM core itself). Clock and reset control instead lives in a
     small SoC-level "SHIM" Control register peephole. BCMA_IOCTL and
     BCMA_RESET_CTL accesses on those cores must be synthesized
     against the SHIM Control register.

The brcm,bus-axi DT path is unchanged.
SoCs with those constraints instantiate bcma-host-soc programmatically
from a parent bridge driver (e.g. the BCM6362 WLAN SHIM bridge, added
in a later patch), supplying a struct bcma_host_soc_pdata that selects
big-endian accessors and provides an already-mapped pointer to the SHIM
Control register peephole.

Internal changes in this patch:

  - Add include/linux/platform_data/bcma_host_soc.h carrying the new
    pdata structure (big_endian, shim_attached, shim_iomem).
  - Add big_endian, shim_attached and shim_iomem fields to
    struct bcma_bus.
  - In drivers/bcma/host_soc.c, add a parallel set of BE accessors
    (read16/read32/write16/write32 and aread32/awrite32) plus a
    synth path that routes BCMA_IOCTL and BCMA_RESET_CTL accesses on
    wrapper-less cores through the SHIM Control register. The new
    bcma_host_soc_ops_brcm_shim ops table groups them.
  - bcma_host_soc_probe() now reads pdata (when present) and selects
    big-endian ops + SHIM routing accordingly. bus->mmio is mapped
    via devm_platform_ioremap_resource() so the same code path works
    whether the platform_device came from DT (resource via reg
    property) or was synthesized by a parent (resource passed in
    platform_device_info::res).
  - In drivers/bcma/scan.c, bcma_scan_read32() and
    bcma_erom_get_ent() honour bus->big_endian.

Assisted-by: Claude:claude-4.8-opus
Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>
---
 drivers/bcma/host_soc.c                     | 224 ++++++++++++++++++++++++++--
 drivers/bcma/scan.c                         |   4 +-
 include/linux/bcma/bcma.h                   |  14 ++
 include/linux/platform_data/bcma_host_soc.h |  31 ++++
 4 files changed, 260 insertions(+), 13 deletions(-)

diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c
index 20b1816c570b..f39129fb9cf2 100644
--- a/drivers/bcma/host_soc.c
+++ b/drivers/bcma/host_soc.c
@@ -10,6 +10,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
+#include <linux/platform_data/bcma_host_soc.h>
 #include <linux/bcma/bcma.h>
 #include <linux/bcma/bcma_soc.h>
 
@@ -165,6 +166,195 @@ static const struct bcma_host_ops bcma_host_soc_ops = {
 	.awrite32	= bcma_host_soc_awrite32,
 };
 
+/* SHIM peephole layout, subset of the OEM "WlanShimRegs" struct: only
+ * the per-core Control registers are needed for IOCTL / RESET_CTL
+ * routing. The low 16 bits of each Control register map bit-for-bit to
+ * BCMA_IOCTL; bit 16 (SICF_WOC_CORE_RESET) is the per-core wrapper
+ * BCMA_RESET_CTL bit 0 promoted into the SHIM Control register.
+ */
+#define BCMA_SHIM_CC_CONTROL		0x08
+#define BCMA_SHIM_MAC_CONTROL		0x10
+#define   SICF_WOC_CORE_RESET		0x10000
+
+/* Resolve the SHIM Control register for a given core: ChipCommon and
+ * the IEEE 802.11 core. Returns NULL for any other core, including the
+ * SHIM core itself - the SHIM has been running since boot and needs no
+ * gating from bcma_core_enable().
+ */
+static void __iomem *bcma_host_soc_shim_ctrl_reg(struct bcma_device *core)
+{
+	void __iomem *shim = core->bus->shim_iomem;
+
+	if (!shim)
+		return NULL;
+
+	switch (core->id.id) {
+	case BCMA_CORE_CHIPCOMMON:
+		return shim + BCMA_SHIM_CC_CONTROL;
+	case BCMA_CORE_80211:
+		return shim + BCMA_SHIM_MAC_CONTROL;
+	}
+	return NULL;
+}
+
+/* Synthesize wrapper-register responses for cores whose DMP wrapper
+ * space does not exist in the standard bcma layout. On SoCs that
+ * publish a SHIM-style mini-EROM (BMIPS xDSL family: BCM6362, ...)
+ * ChipCommon and the 802.11 core report NMW=NSW=0; clock and reset
+ * gating happens in the SHIM's per-core Control register, which is
+ * where this synth routes BCMA_IOCTL and BCMA_RESET_CTL accesses.
+ */
+static u32 bcma_host_soc_synth_aread32(struct bcma_device *core, u16 offset)
+{
+	void __iomem *ctrl_reg = bcma_host_soc_shim_ctrl_reg(core);
+
+	switch (offset) {
+	case BCMA_IOCTL:
+		/* Low 16 bits of the SHIM Control register map bit-for-bit
+		 * to BCMA_IOCTL. Returning the live value lets
+		 * bcma_core_is_enabled() observe a prior disable that
+		 * cleared CLOCK_EN/FGC. For cores not in the SHIM map
+		 * (e.g. the SHIM core itself) return BCMA_IOCTL_CLK so
+		 * the core is treated as already-up; the SHIM has been
+		 * running since boot and has nothing to enable.
+		 */
+		if (ctrl_reg)
+			return ioread32be(ctrl_reg) & 0xFFFF;
+		return BCMA_IOCTL_CLK;
+
+	case BCMA_IOST:
+		/* IOST is synthesized rather than read from the SHIM
+		 * Status register: while the d11 is in reset, MacStatus's
+		 * SISF_CORE_BITS field is unreliable (observed: 0x1008 on
+		 * a disabled d11, where the "2G_PHY" indicator bit 0 is
+		 * clear, which would steer b43 down a nonexistent 5 GHz
+		 * path on a 2.4 GHz-only single-die part).
+		 *
+		 * Synthesize a stable IOST for the 802.11 core:
+		 *   bit 0  (2G_PHY)         = 1   single-die 2.4 GHz
+		 *   bit 1  (5G_PHY)         = 0   no 5 GHz radio wired
+		 *   bit 12 (BCMA_IOST_DMA64)= 1   corerev 22 is DMA64
+		 *
+		 * Other cores have no defined IOST bits of interest.
+		 */
+		if (core->id.id == BCMA_CORE_80211)
+			return 0x01 | BCMA_IOST_DMA64;
+		return 0;
+
+	case BCMA_RESET_CTL:
+		/* SICF_WOC_CORE_RESET is the wrapper RESET_CTL bit 0 in
+		 * the SHIM Control register.
+		 */
+		if (ctrl_reg)
+			return (ioread32be(ctrl_reg) & SICF_WOC_CORE_RESET) ? 1 : 0;
+		return 0;
+
+	case BCMA_RESET_ST:
+		/* No "reset pending" semantics in the SHIM Control reg. */
+		return 0;
+
+	default:
+		pr_info("bcma: synth aread32 unhandled offset 0x%03x on core idx=%u id=0x%x\n",
+			offset, core->core_index, core->id.id);
+		return 0;
+	}
+}
+
+static void bcma_host_soc_synth_awrite32(struct bcma_device *core,
+					 u16 offset, u32 value)
+{
+	void __iomem *ctrl_reg = bcma_host_soc_shim_ctrl_reg(core);
+	u32 cur, new_val;
+
+	if (ctrl_reg) {
+		switch (offset) {
+		case BCMA_IOCTL:
+			/* SICF low 16 bits == BCMA_IOCTL. Preserve
+			 * SICF_WOC_CORE_RESET (the RESET_CTL view) so an
+			 * IOCTL write does not accidentally release reset.
+			 */
+			cur = ioread32be(ctrl_reg);
+			new_val = (value & 0xFFFF) |
+				  (cur & SICF_WOC_CORE_RESET);
+			iowrite32be(new_val, ctrl_reg);
+			pr_debug("bcma: synth IOCTL core=0x%x SHIM %08x->%08x (req %08x)\n",
+				 core->id.id, cur, new_val, value);
+			return;
+		case BCMA_RESET_CTL:
+			cur = ioread32be(ctrl_reg);
+			if (value & 1)
+				new_val = cur | SICF_WOC_CORE_RESET;
+			else
+				new_val = cur & ~SICF_WOC_CORE_RESET;
+			iowrite32be(new_val, ctrl_reg);
+			pr_debug("bcma: synth RESET_CTL core=0x%x SHIM %08x->%08x (req %08x)\n",
+				 core->id.id, cur, new_val, value);
+			return;
+		}
+	}
+
+	pr_info("bcma: synth awrite32 dropped on core idx=%u id=0x%x offset=0x%03x value=0x%08x\n",
+		core->core_index, core->id.id, offset, value);
+}
+
+/* Big-endian accessor variants for SoCs whose AXI backplane sits on a
+ * big-endian peripheral bus (BMIPS xDSL family). read8/write8 are
+ * endian-agnostic byte accesses and reuse the LE helpers above.
+ * CONFIG_BCMA_BLOCKIO block_read/write are intentionally omitted: those
+ * targets do not enable block I/O. aread32/awrite32 dispatch to the
+ * synthesizer when core->io_wrap is NULL (legitimate on SHIM-attached
+ * cores; that NULL state is allow-listed in scan.c).
+ */
+static u32 bcma_host_soc_read32_be(struct bcma_device *core, u16 offset)
+{
+	return ioread32be(core->io_addr + offset);
+}
+
+static u16 bcma_host_soc_read16_be(struct bcma_device *core, u16 offset)
+{
+	return ioread16be(core->io_addr + offset);
+}
+
+static void bcma_host_soc_write32_be(struct bcma_device *core, u16 offset,
+				     u32 value)
+{
+	iowrite32be(value, core->io_addr + offset);
+}
+
+static void bcma_host_soc_write16_be(struct bcma_device *core, u16 offset,
+				     u16 value)
+{
+	iowrite16be(value, core->io_addr + offset);
+}
+
+static u32 bcma_host_soc_aread32_be(struct bcma_device *core, u16 offset)
+{
+	if (likely(core->io_wrap))
+		return ioread32be(core->io_wrap + offset);
+	return bcma_host_soc_synth_aread32(core, offset);
+}
+
+static void bcma_host_soc_awrite32_be(struct bcma_device *core, u16 offset,
+				      u32 value)
+{
+	if (likely(core->io_wrap)) {
+		iowrite32be(value, core->io_wrap + offset);
+		return;
+	}
+	bcma_host_soc_synth_awrite32(core, offset, value);
+}
+
+static const struct bcma_host_ops bcma_host_soc_ops_brcm_shim = {
+	.read8		= bcma_host_soc_read8,
+	.read16		= bcma_host_soc_read16_be,
+	.read32		= bcma_host_soc_read32_be,
+	.write8		= bcma_host_soc_write8,
+	.write16	= bcma_host_soc_write16_be,
+	.write32	= bcma_host_soc_write32_be,
+	.aread32	= bcma_host_soc_aread32_be,
+	.awrite32	= bcma_host_soc_awrite32_be,
+};
+
 int __init bcma_host_soc_register(struct bcma_soc *soc)
 {
 	struct bcma_bus *bus = &soc->bus;
@@ -202,8 +392,8 @@ int __init bcma_host_soc_init(struct bcma_soc *soc)
 #ifdef CONFIG_OF
 static int bcma_host_soc_probe(struct platform_device *pdev)
 {
+	struct bcma_host_soc_pdata *pdata = dev_get_platdata(&pdev->dev);
 	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
 	struct bcma_bus *bus;
 	int err;
 
@@ -214,14 +404,26 @@ static int bcma_host_soc_probe(struct platform_device *pdev)
 
 	bus->dev = dev;
 
-	/* Map MMIO */
-	bus->mmio = of_iomap(np, 0);
-	if (!bus->mmio)
-		return -ENOMEM;
+	/* Map MMIO. devm_platform_ioremap_resource() consumes the first
+	 * IORESOURCE_MEM regardless of whether it came from a DT reg
+	 * property (legacy brcm,bus-axi path) or from a synthesized
+	 * platform_device_info::res (SHIM-attached path).
+	 */
+	bus->mmio = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(bus->mmio))
+		return PTR_ERR(bus->mmio);
 
 	/* Host specific */
 	bus->hosttype = BCMA_HOSTTYPE_SOC;
-	bus->ops = &bcma_host_soc_ops;
+	if (pdata) {
+		bus->big_endian    = pdata->big_endian;
+		bus->shim_attached = pdata->shim_attached;
+		bus->shim_iomem    = pdata->shim_iomem;
+		bus->ops = pdata->big_endian ? &bcma_host_soc_ops_brcm_shim
+					     : &bcma_host_soc_ops;
+	} else {
+		bus->ops = &bcma_host_soc_ops;
+	}
 
 	/* Initialize struct, detect chip */
 	bcma_init_bus(bus);
@@ -229,15 +431,11 @@ static int bcma_host_soc_probe(struct platform_device *pdev)
 	/* Register */
 	err = bcma_bus_register(bus);
 	if (err)
-		goto err_unmap_mmio;
+		return err;
 
 	platform_set_drvdata(pdev, bus);
 
 	return err;
-
-err_unmap_mmio:
-	iounmap(bus->mmio);
-	return err;
 }
 
 static void bcma_host_soc_remove(struct platform_device *pdev)
@@ -245,7 +443,9 @@ static void bcma_host_soc_remove(struct platform_device *pdev)
 	struct bcma_bus *bus = platform_get_drvdata(pdev);
 
 	bcma_bus_unregister(bus);
-	iounmap(bus->mmio);
+	/* bus->mmio is devm-managed; shim_iomem is borrowed from the
+	 * parent bridge driver and must not be unmapped here.
+	 */
 	platform_set_drvdata(pdev, NULL);
 }
 
diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 84742408a59c..983a62ddeebb 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -143,6 +143,8 @@ static const char *bcma_device_name(const struct bcma_device_id *id)
 
 static u32 bcma_scan_read32(struct bcma_bus *bus, u16 offset)
 {
+	if (bus->big_endian)
+		return ioread32be(bus->mmio + offset);
 	return readl(bus->mmio + offset);
 }
 
@@ -155,7 +157,7 @@ static void bcma_scan_switch_core(struct bcma_bus *bus, u32 addr)
 
 static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 __iomem **eromptr)
 {
-	u32 ent = readl(*eromptr);
+	u32 ent = bus->big_endian ? ioread32be(*eromptr) : readl(*eromptr);
 	(*eromptr)++;
 	return ent;
 }
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 60b94b944e9f..aaa6c5674c2a 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -362,6 +362,20 @@ struct bcma_bus {
 	/* We decided to share SPROM struct with SSB as long as we do not need
 	 * any hacks for BCMA. This simplifies drivers code. */
 	struct ssb_sprom sprom;
+
+	/* SoC quirks populated from struct bcma_host_soc_pdata when a
+	 * SHIM-attached parent bridge driver instantiates the bcma-host-soc
+	 * child platform_device. big_endian selects ioread/iowrite *be
+	 * helpers on the scan and host_soc accessor paths; shim_attached
+	 * tells scan.c that wrapper-less cores (NMW=NSW=0) are legitimate
+	 * on this backplane; shim_iomem points at the SoC-level SHIM
+	 * Control register peephole that host_soc.c routes per-core
+	 * BCMA_IOCTL / BCMA_RESET_CTL accesses through. shim_iomem is
+	 * borrowed from the parent and must not be unmapped here.
+	 */
+	bool big_endian;
+	bool shim_attached;
+	void __iomem *shim_iomem;
 };
 
 static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
diff --git a/include/linux/platform_data/bcma_host_soc.h b/include/linux/platform_data/bcma_host_soc.h
new file mode 100644
index 000000000000..e1e7c5acb574
--- /dev/null
+++ b/include/linux/platform_data/bcma_host_soc.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#ifndef _LINUX_PLATFORM_DATA_BCMA_HOST_SOC_H
+#define _LINUX_PLATFORM_DATA_BCMA_HOST_SOC_H
+
+#include <linux/types.h>
+
+/**
+ * struct bcma_host_soc_pdata - SoC-specific configuration for bcma-host-soc.
+ *
+ * Used by parent bridge drivers that instantiate bcma-host-soc as a child
+ * platform_device (e.g. the BCM6362 WLAN SHIM bridge). The legacy
+ * brcm,bus-axi DT path uses default values and does not supply this.
+ *
+ * @big_endian:    Backplane registers are big-endian peripherals on a
+ *                 big-endian CPU. Selects ioread/iowrite *be helpers for
+ *                 all bcma register accesses on this bus.
+ * @shim_attached: Cores on this backplane do not publish per-core DMP
+ *                 wrappers (NMW=NSW=0 in the EROM); clock and reset
+ *                 gating instead lives in a SoC-level "SHIM" Control
+ *                 register peephole reached through @shim_iomem.
+ * @shim_iomem:    Pre-mapped iomem pointer for the SHIM peephole.
+ *                 Lifetime is owned by the parent bridge driver; the
+ *                 bcma-host-soc driver must not iounmap it.
+ */
+struct bcma_host_soc_pdata {
+	bool		big_endian;
+	bool		shim_attached;
+	void __iomem	*shim_iomem;
+};
+
+#endif /* _LINUX_PLATFORM_DATA_BCMA_HOST_SOC_H */

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/4] bcma: allow SHIM-style mini-EROM wrapper-less cores in scan
  2026-05-29  0:05 [PATCH 0/4] bcma: support SHIM-attached big-endian SoC backplanes (BCM6362) Alessio Ferri
  2026-05-29  0:05 ` [PATCH 1/4] bcma: support driver specific quirks from soc pdata Alessio Ferri
@ 2026-05-29  0:06 ` Alessio Ferri
  2026-05-29  1:25   ` sashiko-bot
  2026-05-29  0:06 ` [PATCH 3/4] dt-bindings: bus: add brcm,bcm6362-wlan Alessio Ferri
  2026-05-29  0:06 ` [PATCH 4/4] bus: add BCM6362 on-chip WLAN SHIM bridge driver Alessio Ferri
  3 siblings, 1 reply; 9+ messages in thread
From: Alessio Ferri @ 2026-05-29  0:06 UTC (permalink / raw)
  To: Rafał Miłecki, Alessio Ferri, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Florian Fainelli
  Cc: linux-kernel, linux-wireless, devicetree

bcma_get_next_core() rejects with -ENXIO any component whose
component_B descriptor reports NMW=NSW=0 unless its core id is in
a short allowlist (4706 MAC GBIT, NS_CHIPCOMMON_B, PMU, GCI).

On SoCs that publish a SHIM-style mini-EROM (i.e. BCM6362) the
WLAN backplane lists three components:
ChipCommon, IEEE 802.11 and BCMA_CORE_SHIM. None of the three is
in the existing allowlist, so all three are skipped silently,
bus->cores stays empty, bcma_find_core(BCMA_CORE_CHIPCOMMON)
returns NULL, and a later bcma_chipco_watchdog_register()
dereferences cc->core->bus on its first line and oopses mid-probe.

Assisted-by: Claude:claude-4.8-opus
Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>
---
 drivers/bcma/scan.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 983a62ddeebb..782fc53eb6b3 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -318,6 +318,21 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
 		case BCMA_CORE_GCI:
 		/* Not used yet: case BCMA_CORE_OOB_ROUTER: */
 			break;
+		case BCMA_CORE_CHIPCOMMON:
+		case BCMA_CORE_80211:
+		case BCMA_CORE_SHIM:
+			/* SHIM-style mini-EROM SoCs publish CHIPCOMMON, the
+			 * IEEE 802.11 core and the SHIM core itself with
+			 * NMW=NSW=0 because clock and reset gating happens
+			 * at the SoC level via the SHIM Control register,
+			 * not via per-core DMP wrappers. host_soc.c sets
+			 * bus->shim_attached on those SoCs from pdata; the
+			 * strict NMW=NSW=0 rejection still applies to PCI-
+			 * attached cards and to SoCs without that quirk.
+			 */
+			if (bus->shim_attached)
+				break;
+			fallthrough;
 		default:
 			bcma_erom_skip_component(bus, eromptr);
 			return -ENXIO;

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/4] dt-bindings: bus: add brcm,bcm6362-wlan
  2026-05-29  0:05 [PATCH 0/4] bcma: support SHIM-attached big-endian SoC backplanes (BCM6362) Alessio Ferri
  2026-05-29  0:05 ` [PATCH 1/4] bcma: support driver specific quirks from soc pdata Alessio Ferri
  2026-05-29  0:06 ` [PATCH 2/4] bcma: allow SHIM-style mini-EROM wrapper-less cores in scan Alessio Ferri
@ 2026-05-29  0:06 ` Alessio Ferri
  2026-05-29  1:36   ` sashiko-bot
  2026-05-29  0:06 ` [PATCH 4/4] bus: add BCM6362 on-chip WLAN SHIM bridge driver Alessio Ferri
  3 siblings, 1 reply; 9+ messages in thread
From: Alessio Ferri @ 2026-05-29  0:06 UTC (permalink / raw)
  To: Rafał Miłecki, Alessio Ferri, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Florian Fainelli
  Cc: linux-kernel, linux-wireless, devicetree

Document the binding for the SHIM bridge that gates the on-chip
2.4 GHz WLAN block of the Broadcom BCM6362 SoC. The bridge owns the
SHIM peephole, a single clock for the macro, and two resets (the
SHIM macro itself and its ubus side). It is also a bus: it carries
one brcm,bus-axi child describing the bcma backplane behind the
SHIM, with a standard interrupt-map routing the d11 core's IRQ to
the SoC interrupt controller.

Assisted-by: Claude:claude-4.8-opus
Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>
---
 .../devicetree/bindings/bus/brcm,bcm6362-wlan.yaml | 106 +++++++++++++++++++++
 1 file changed, 106 insertions(+)

diff --git a/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan.yaml b/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan.yaml
new file mode 100644
index 000000000000..c8d49ccdd2c1
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan.yaml
@@ -0,0 +1,106 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bus/brcm,bcm6362-wlan.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM6362 on-chip WLAN SHIM bridge
+
+maintainers:
+  - Alessio Ferri <alessio.ferri@mythread.it>
+
+description: |
+  The BCM6362 SoC integrates a 2.4 GHz Broadcom WLAN block whose
+  register backplane uses the Broadcom AMBA (bcma) architecture. The
+  backplane is gated by a small SHIM bridge that holds the WLAN macro
+  in reset and disables its clocks until released by software. CFE
+  does not release this block, so software bring-up is required
+  before bcma can enumerate the backplane.
+
+  This binding describes the SHIM bridge node. The SHIM driver brings
+  the macro up and then populates the brcm,bus-axi child node, which
+  describes the bcma backplane behind the SHIM and is bound by the
+  bcma-host-soc driver. The SoC-specific configuration (big-endian
+  accessors, SHIM-attached topology, SHIM Control register peephole
+  pointer) is delivered to bcma via platform_data injected at
+  populate time, so the brcm,bus-axi child stays SoC-agnostic.
+
+properties:
+  compatible:
+    const: brcm,bcm6362-wlan
+
+  reg:
+    maxItems: 1
+    description: SHIM peephole registers.
+
+  reg-names:
+    items:
+      - const: shim
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    items:
+      - description: SHIM macro reset
+      - description: SHIM ubus reset
+
+  reset-names:
+    items:
+      - const: shim
+      - const: shim-ubus
+
+  '#address-cells':
+    const: 1
+
+  '#size-cells':
+    const: 1
+
+  ranges: true
+
+patternProperties:
+  "^axi@[0-9a-f]+$":
+    type: object
+    description: The bcma AXI backplane behind the SHIM.
+    $ref: /schemas/types.yaml#
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - resets
+  - reset-names
+  - '#address-cells'
+  - '#size-cells'
+  - ranges
+
+additionalProperties: false
+
+examples:
+  - |
+    wlan@10007000 {
+        compatible = "brcm,bcm6362-wlan";
+        reg = <0x10007000 0x100>;
+        reg-names = "shim";
+        clocks = <&periph_clk 11>;
+        resets = <&periph_rst 7>, <&periph_rst 17>;
+        reset-names = "shim", "shim-ubus";
+
+        #address-cells = <1>;
+        #size-cells = <1>;
+        ranges;
+
+        axi@10004000 {
+            compatible = "brcm,bus-axi";
+            reg = <0x10004000 0x1000>;
+            ranges = <0x00000000 0x10004000 0x00002000>;
+
+            #address-cells = <1>;
+            #size-cells = <1>;
+            #interrupt-cells = <1>;
+
+            interrupt-map-mask = <0x000fffff 0xffff>;
+            interrupt-map = <0x00005000 0 &periph_intc 0 12>;
+        };
+    };

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/4] bus: add BCM6362 on-chip WLAN SHIM bridge driver
  2026-05-29  0:05 [PATCH 0/4] bcma: support SHIM-attached big-endian SoC backplanes (BCM6362) Alessio Ferri
                   ` (2 preceding siblings ...)
  2026-05-29  0:06 ` [PATCH 3/4] dt-bindings: bus: add brcm,bcm6362-wlan Alessio Ferri
@ 2026-05-29  0:06 ` Alessio Ferri
  2026-05-29  2:02   ` sashiko-bot
  3 siblings, 1 reply; 9+ messages in thread
From: Alessio Ferri @ 2026-05-29  0:06 UTC (permalink / raw)
  To: Rafał Miłecki, Alessio Ferri, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Philipp Zabel,
	Florian Fainelli
  Cc: linux-kernel, linux-wireless, devicetree

Add the bridge driver that brings up the BCM6362 on-chip WLAN SHIM
and then populates a brcm,bus-axi child whose backplane is
enumerated by drivers/bcma/host_soc.c.

Add myself as MANTAINER for this shim.

After mapping the SHIM peephole, preparing the clock, and toggling
the SHIM and ubus resets, the driver runs the macro-enable sequence
taken from the OEM BCM6362 SDK setup.c. It then constructs a struct
bcma_host_soc_pdata - with big_endian and shim_attached set, and
shim_iomem pointing at the already-mapped SHIM peephole - and hands
it to the brcm,bus-axi child by registering an of_dev_auxdata entry
keyed on the "brcm,bus-axi" compatible. of_platform_populate() then
creates the child platform_device with the pdata attached, and
bcma-host-soc consumes it during its probe.

The auxdata-based handoff was chosen over a second per-SoC
bcma-host-soc DT compatible to keep the SoC-specific knowledge in
the SHIM driver, where the SHIM register layout already lives, and
to avoid duplicating the SHIM base address between the DT and the
bcma driver. Using of_platform_populate() rather than a synthesized
platform_device preserves the DT IRQ machinery: the bcma child's
of_node carries the standard interrupt-map that bcma_of_get_irq()
walks to resolve per-core IRQs.

Assisted-by: Claude:claude-4.8-opus
Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>
---
 MAINTAINERS                     |   7 ++
 drivers/bus/Kconfig             |  13 +++
 drivers/bus/Makefile            |   1 +
 drivers/bus/bcm6362-wlan-shim.c | 252 ++++++++++++++++++++++++++++++++++++++++
 4 files changed, 273 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 461a3eed6129..4032bd6b9cfa 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5109,6 +5109,13 @@ L:	linux-usb@vger.kernel.org
 S:	Maintained
 F:	drivers/usb/gadget/udc/bcm63xx_udc.*
 
+BROADCOM BCM6362 WLAN SHIM BRIDGE DRIVER
+M:	Alessio Ferri <alessio.ferri@mythread.it>
+L:	linux-wireless@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan.yaml
+F:	drivers/bus/bcm6362-wlan-shim.c
+
 BROADCOM BCM7XXX ARM ARCHITECTURE
 M:	Florian Fainelli <florian.fainelli@broadcom.com>
 R:	Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
index 3181d8aa32a3..e992a34c5230 100644
--- a/drivers/bus/Kconfig
+++ b/drivers/bus/Kconfig
@@ -29,6 +29,19 @@ config ARM_INTEGRATOR_LM
 	  Say y here to enable support for the ARM Logic Module bus
 	  found on the ARM Integrator AP (Application Platform)
 
+config BCM6362_WLAN_SHIM
+	tristate "BCM6362 on-chip WLAN SHIM bridge"
+	depends on BMIPS_GENERIC || COMPILE_TEST
+	depends on OF
+	select BCMA
+	select BCMA_HOST_SOC
+	help
+	  Bring-up driver for the SHIM bridge that gates the integrated
+	  2.4 GHz WLAN block of the BCM6362 SoC. The driver releases the
+	  SHIM from reset, configures clocks, and then instantiates a
+	  bcma-host-soc child platform device whose bcma backplane is
+	  enumerated by the bcma driver.
+
 config BRCMSTB_GISB_ARB
 	tristate "Broadcom STB GISB bus arbiter"
 	depends on ARCH_BRCMSTB || BMIPS_GENERIC
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile
index a01f97fef3e8..4b24ce0137fc 100644
--- a/drivers/bus/Makefile
+++ b/drivers/bus/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_ARM_CCI)		+= arm-cci.o
 obj-$(CONFIG_ARM_INTEGRATOR_LM)	+= arm-integrator-lm.o
 obj-$(CONFIG_HISILICON_LPC)	+= hisi_lpc.o
 obj-$(CONFIG_BRCMSTB_GISB_ARB)	+= brcmstb_gisb.o
+obj-$(CONFIG_BCM6362_WLAN_SHIM)	+= bcm6362-wlan-shim.o
 obj-$(CONFIG_MOXTET)		+= moxtet.o
 
 # DPAA2 fsl-mc bus
diff --git a/drivers/bus/bcm6362-wlan-shim.c b/drivers/bus/bcm6362-wlan-shim.c
new file mode 100644
index 000000000000..a2de03cf8ff7
--- /dev/null
+++ b/drivers/bus/bcm6362-wlan-shim.c
@@ -0,0 +1,252 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * BCM6362 on-chip WLAN SHIM bridge driver.
+ *
+ * The BCM6362 integrates a Broadcom 2.4 GHz WLAN block whose register
+ * backplane is a Broadcom AMBA (AXI/OCP) - what the bcma driver calls
+ * "brcm,bus-axi". The backplane sits on the SoC ubus, behind a small
+ * "SHIM" bridge that gates clocks and holds the WLAN macro in reset
+ * until released by software. CFE does not bring this block up.
+ *
+ *   ubus  ─┬─►  WLAN SHIM  ─►  AXI backplane  ┬─► ChipCommon
+ *          │    @ 0x10007000  @ 0x10004000    ├─► d11 MAC core
+ *          │                                  └─► (PMU, GPIO live in
+ *          │                                       ChipCommon)
+ *          └─►  rest of the SoC
+ *
+ * This driver brings the SHIM up (clocks, resets, the OEM enable
+ * sequence) and then calls of_platform_populate() on its DT node. The
+ * "brcm,bus-axi" child is bound by drivers/bcma/host_soc.c, and the
+ * SoC-specific configuration that bcma needs (big-endian backplane,
+ * SHIM-attached topology, and an already-mapped pointer to the SHIM
+ * Control register peephole) is delivered to it via of_dev_auxdata
+ * platform_data injected at populate time.
+ *
+ * Bring-up sequence and SHIM register layout match the OEM source
+ * arch/mips/bcm963xx/setup.c and the WlanShimRegs struct in
+ * shared/opensource/include/bcm963xx/6362_map_part.h. The fake-PCI
+ * dance the OEM kernel does after bring-up is intentionally absent
+ * here: bcma host_soc.c speaks to the backplane natively, in
+ * big-endian, via the pdata-supplied configuration.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/platform_data/bcma_host_soc.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+/* SHIM register layout (struct WlanShimRegs in 6362_map_part.h). */
+#define SHIM_MISC		0x00
+#define   SHIM_FORCE_CLK_ON	BIT(2)
+#define   SHIM_MACRO_DISABLE	BIT(1)
+#define   SHIM_MACRO_SOFT_RESET	BIT(0)
+#define SHIM_STATUS		0x04
+#define SHIM_CC_CONTROL		0x08
+#define SHIM_CC_STATUS		0x0c
+#define SHIM_MAC_CONTROL	0x10
+#define   SICF_FGC		BIT(1)	/* force gated clock */
+#define   SICF_CLOCK_EN		BIT(0)
+#define SHIM_MAC_STATUS		0x14
+#define SHIM_CC_ID_A		0x18
+#define SHIM_MAC_ID_A		0x24
+
+struct bcm6362_wlan {
+	struct device		*dev;
+	void __iomem		*shim;
+	struct clk		*clk;
+	struct reset_control	*rst_shim;
+	struct reset_control	*rst_shim_ubus;
+
+	/* Storage for the pdata pointer handed to bcma via of_dev_auxdata.
+	 * of_platform_device_create_pdata() stores a pointer to this
+	 * struct on the bcma child device's platform_data field, so it
+	 * must outlive the child. devm_kzalloc on priv guarantees this:
+	 * the child is depopulated in remove() before devres frees priv.
+	 */
+	struct bcma_host_soc_pdata pdata;
+};
+
+static int bcm6362_wlan_bringup(struct bcm6362_wlan *priv)
+{
+	int ret;
+
+	dev_info(priv->dev, "bring-up: start\n");
+
+	ret = clk_prepare_enable(priv->clk);
+	if (ret) {
+		dev_err(priv->dev, "clk_prepare_enable failed: %d\n", ret);
+		return ret;
+	}
+	dev_info(priv->dev, "bring-up: clock enabled, rate=%lu Hz\n",
+		 clk_get_rate(priv->clk));
+	mdelay(10);
+
+	/* Reset toggle (brcm,bcm6345-reset hides the active-low softResetB
+	 * encoding, so assert/deassert read naturally here).
+	 */
+	reset_control_assert(priv->rst_shim_ubus);
+	reset_control_assert(priv->rst_shim);
+	mdelay(1);
+	reset_control_deassert(priv->rst_shim_ubus);
+	reset_control_deassert(priv->rst_shim);
+	mdelay(1);
+	dev_info(priv->dev, "bring-up: reset toggled\n");
+
+	/* The SHIM and the AXI backplane behind it are big-endian
+	 * peripherals on a big-endian MIPS CPU. The asymmetric-endian
+	 * writel() in this configuration byte-swaps the value (it
+	 * assumes a little-endian bus, typical for PCI), landing each
+	 * bit in the wrong position. iowrite32be() is a no-op transform
+	 * here (BE-to-BE) and writes the value the bring-up sequence
+	 * intends. Same story for the read-back diagnostics: readl()
+	 * would byte-swap on the way back.
+	 *
+	 * Force clocks on + hold WLAN macro in soft reset.
+	 */
+	iowrite32be(SHIM_FORCE_CLK_ON | SHIM_MACRO_SOFT_RESET,
+		    priv->shim + SHIM_MISC);
+	mdelay(1);
+
+	/* MAC core: force gated clock + clock enable (with reset held). */
+	iowrite32be(SICF_FGC | SICF_CLOCK_EN, priv->shim + SHIM_MAC_CONTROL);
+
+	/* Release macro soft reset, keep clocks forced. */
+	iowrite32be(SHIM_FORCE_CLK_ON, priv->shim + SHIM_MISC);
+
+	/* Drop the force, let normal gating take over. */
+	iowrite32be(0, priv->shim + SHIM_MISC);
+	iowrite32be(SICF_CLOCK_EN, priv->shim + SHIM_MAC_CONTROL);
+
+	/* Read-back diagnostics: if the backplane is alive these reflect
+	 * the values we just wrote (MISC=0, MAC_CONTROL=SICF_CLOCK_EN) and
+	 * the STATUS regs report sane non-zero core ids.
+	 */
+	dev_info(priv->dev,
+		 "bring-up: post-shim MISC=%08x STATUS=%08x CC_CTRL=%08x CC_STAT=%08x MAC_CTRL=%08x MAC_STAT=%08x\n",
+		 ioread32be(priv->shim + SHIM_MISC),
+		 ioread32be(priv->shim + SHIM_STATUS),
+		 ioread32be(priv->shim + SHIM_CC_CONTROL),
+		 ioread32be(priv->shim + SHIM_CC_STATUS),
+		 ioread32be(priv->shim + SHIM_MAC_CONTROL),
+		 ioread32be(priv->shim + SHIM_MAC_STATUS));
+	dev_info(priv->dev,
+		 "bring-up: CcIdA=%08x MacIdA=%08x (non-zero = backplane responsive)\n",
+		 ioread32be(priv->shim + SHIM_CC_ID_A),
+		 ioread32be(priv->shim + SHIM_MAC_ID_A));
+
+	return 0;
+}
+
+static void bcm6362_wlan_teardown(struct bcm6362_wlan *priv)
+{
+	iowrite32be(0, priv->shim + SHIM_MAC_CONTROL);
+	iowrite32be(SHIM_MACRO_DISABLE | SHIM_MACRO_SOFT_RESET,
+		    priv->shim + SHIM_MISC);
+	reset_control_assert(priv->rst_shim);
+	reset_control_assert(priv->rst_shim_ubus);
+	clk_disable_unprepare(priv->clk);
+}
+
+static int bcm6362_wlan_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct of_dev_auxdata auxdata[2];
+	struct bcm6362_wlan *priv;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+	priv->dev = dev;
+
+	priv->shim = devm_platform_ioremap_resource_byname(pdev, "shim");
+	if (IS_ERR(priv->shim))
+		return PTR_ERR(priv->shim);
+
+	priv->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(priv->clk))
+		return PTR_ERR(priv->clk);
+
+	priv->rst_shim = devm_reset_control_get_exclusive(dev, "shim");
+	if (IS_ERR(priv->rst_shim))
+		return PTR_ERR(priv->rst_shim);
+
+	priv->rst_shim_ubus = devm_reset_control_get_exclusive(dev,
+							       "shim-ubus");
+	if (IS_ERR(priv->rst_shim_ubus))
+		return PTR_ERR(priv->rst_shim_ubus);
+
+	ret = bcm6362_wlan_bringup(priv);
+	if (ret) {
+		dev_err(dev, "WLAN bring-up failed: %d\n", ret);
+		return ret;
+	}
+
+	/* Configure pdata in storage owned by priv. Used by
+	 * of_platform_populate() below and dereferenced by bcma at
+	 * runtime via dev_get_platdata().
+	 */
+	priv->pdata.big_endian	  = true;
+	priv->pdata.shim_attached = true;
+	priv->pdata.shim_iomem	  = priv->shim;
+
+	/* Inject pdata into the brcm,bus-axi child at populate time.
+	 * phys_addr 0 matches by compatible only; there is exactly one
+	 * brcm,bus-axi child under this node. of_platform_populate()
+	 * triggers the bcma probe synchronously - if bcma is built-in
+	 * (or already loaded as a module - see MODULE_SOFTDEP below)
+	 * it has matched and configured itself before we return here.
+	 */
+	auxdata[0] = (struct of_dev_auxdata)
+		OF_DEV_AUXDATA("brcm,bus-axi", 0, NULL, &priv->pdata);
+	memset(&auxdata[1], 0, sizeof(auxdata[1]));
+
+	ret = of_platform_populate(dev->of_node, NULL, auxdata, dev);
+	if (ret) {
+		dev_err(dev, "failed to populate bcma child: %d\n", ret);
+		bcm6362_wlan_teardown(priv);
+		return ret;
+	}
+
+	platform_set_drvdata(pdev, priv);
+	return 0;
+}
+
+static void bcm6362_wlan_remove(struct platform_device *pdev)
+{
+	struct bcm6362_wlan *priv = platform_get_drvdata(pdev);
+
+	/* Tear bcma down first: the bcma child uses priv->shim through
+	 * pdata->shim_iomem and its lifetime is owned here.
+	 * of_platform_depopulate() is synchronous - by the time it
+	 * returns, bcma has released the SHIM mapping.
+	 */
+	of_platform_depopulate(&pdev->dev);
+	bcm6362_wlan_teardown(priv);
+}
+
+static const struct of_device_id bcm6362_wlan_match[] = {
+	{ .compatible = "brcm,bcm6362-wlan", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, bcm6362_wlan_match);
+
+static struct platform_driver bcm6362_wlan_driver = {
+	.probe	= bcm6362_wlan_probe,
+	.remove	= bcm6362_wlan_remove,
+	.driver	= {
+		.name		= "bcm6362-wlan",
+		.of_match_table	= bcm6362_wlan_match,
+	},
+};
+module_platform_driver(bcm6362_wlan_driver);
+
+MODULE_SOFTDEP("pre: bcma");
+MODULE_AUTHOR("Alessio Ferri <alessio.ferri@mythread.it>");
+MODULE_DESCRIPTION("BCM6362 on-chip WLAN SHIM bridge driver");
+MODULE_LICENSE("GPL");

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 1/4] bcma: support driver specific quirks from soc pdata
  2026-05-29  0:05 ` [PATCH 1/4] bcma: support driver specific quirks from soc pdata Alessio Ferri
@ 2026-05-29  0:48   ` sashiko-bot
  0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-05-29  0:48 UTC (permalink / raw)
  To: Alessio Ferri; +Cc: conor+dt, devicetree, robh

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

New issues:
- [High] Synthesized write to BCMA_IOCTL inadvertently clears bits 17-31 of the SHIM Control register.
- [High] Missing `block_read` and `block_write` callbacks in `bcma_host_soc_ops_brcm_shim` will cause a NULL pointer dereference when CONFIG_BCMA_BLOCKIO is enabled.

Pre-existing issues:
- [High] The bcm47xx_wdt watchdog timer is not canceled when the platform device is unregistered during bus teardown, leading to a Use-After-Free when the software timer expires.
--

commit dfe73fc3413d87faa9dc228ee7a188e34676dd31
Author: Alessio Ferri <alessio.ferri@mythread.it>

bcma: support driver specific quirks from soc pdata

This commit adds support for BMIPS xDSL SoCs by instantiating bcma-host-soc
programmatically and routing accesses through a SHIM Control register. It
also introduces big-endian accessors for SoCs where the AXI backplane
sits on a big-endian peripheral bus.

> diff --git a/drivers/bcma/host_soc.c b/drivers/bcma/host_soc.c
> index 20b1816c570b2..f39129fb9cf29 100644
> --- a/drivers/bcma/host_soc.c
> +++ b/drivers/bcma/host_soc.c
[ ... ]
> @@ -165,6 +166,195 @@ static const struct bcma_host_ops bcma_host_soc_ops = {
[ ... ]
> +static void bcma_host_soc_synth_awrite32(struct bcma_device *core,
> +					 u16 offset, u32 value)
> +{
> +	void __iomem *ctrl_reg = bcma_host_soc_shim_ctrl_reg(core);
> +	u32 cur, new_val;
> +
> +	if (ctrl_reg) {
> +		switch (offset) {
> +		case BCMA_IOCTL:
> +			/* SICF low 16 bits == BCMA_IOCTL. Preserve
> +			 * SICF_WOC_CORE_RESET (the RESET_CTL view) so an
> +			 * IOCTL write does not accidentally release reset.
> +			 */
> +			cur = ioread32be(ctrl_reg);
> +			new_val = (value & 0xFFFF) |
> +				  (cur & SICF_WOC_CORE_RESET);

[Severity: High]
Does this synthesized write inadvertently clear bits 17-31 of the SHIM Control
register?

By only keeping SICF_WOC_CORE_RESET (bit 16) from the current register value,
all other bits from 17 to 31 will be dropped. If the hardware or firmware
relies on any configuration or state in those upper bits, this operation could
lead to register state corruption. Would a mask like (cur & ~0xFFFF) be better
to preserve all unmanaged bits?

> +			iowrite32be(new_val, ctrl_reg);
> +			pr_debug("bcma: synth IOCTL core=0x%x SHIM %08x->%08x (req %08x)\n",
> +				 core->id.id, cur, new_val, value);
> +			return;
[ ... ]
> +static const struct bcma_host_ops bcma_host_soc_ops_brcm_shim = {
> +	.read8		= bcma_host_soc_read8,
> +	.read16		= bcma_host_soc_read16_be,
> +	.read32		= bcma_host_soc_read32_be,
> +	.write8		= bcma_host_soc_write8,
> +	.write16	= bcma_host_soc_write16_be,
> +	.write32	= bcma_host_soc_write32_be,
> +	.aread32	= bcma_host_soc_aread32_be,
> +	.awrite32	= bcma_host_soc_awrite32_be,
> +};

[Severity: High]
Can omitting block_read and block_write callbacks here cause a null pointer
dereference when CONFIG_BCMA_BLOCKIO is enabled?

If a driver like b43 configured in PIO mode calls the bcma_block_read() or
bcma_block_write() inline wrappers, those functions unconditionally call
core->bus->ops->block_read without checking if the pointer is null. Might
these functions need to be safely stubbed out?

> +
>  int __init bcma_host_soc_register(struct bcma_soc *soc)
>  {
[ ... ]
> @@ -245,7 +443,9 @@ static void bcma_host_soc_remove(struct platform_device *pdev)
>  	struct bcma_bus *bus = platform_get_drvdata(pdev);
>  
>  	bcma_bus_unregister(bus);

[Severity: High]
This is a pre-existing issue, but does unregistering the bus cause a
use-after-free with the bcm47xx_wdt watchdog timer?

Calling bcma_bus_unregister() unbinds the bcm47xx_wdt driver. Since the
driver lacks a remove function, it relies on devm_watchdog_unregister_device
for cleanup. However, it does not set WDOG_STOP_ON_UNREGISTER, so if the
watchdog was active, its software timer remains running.

Because the memory holding the timer resides in the platform data, which is
freed immediately upon unregister, will the timer dereference freed memory
when it expires?

> -	iounmap(bus->mmio);
> +	/* bus->mmio is devm-managed; shim_iomem is borrowed from the
> +	 * parent bridge driver and must not be unmapped here.
> +	 */
>  	platform_set_drvdata(pdev, NULL);
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260529-add-bcm6362-wlan-v1-0-722242777f58@gmail.com?part=1

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/4] bcma: allow SHIM-style mini-EROM wrapper-less cores in scan
  2026-05-29  0:06 ` [PATCH 2/4] bcma: allow SHIM-style mini-EROM wrapper-less cores in scan Alessio Ferri
@ 2026-05-29  1:25   ` sashiko-bot
  0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-05-29  1:25 UTC (permalink / raw)
  To: Alessio Ferri; +Cc: devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [High] Unconditional dereference of `cc->core` in dependent modules can cause a kernel Oops if core scanning fails or a core is missing.
- [High] The fallback bridge check in `bcma_get_next_core()` fails to skip the rest of the component's EROM descriptors before returning `-ENXIO`.
--

commit 257794fc3cb2f2e7a20011d91e6239f7a6956709
Author: Alessio Ferri <alessio.ferri@mythread.it>

bcma: allow SHIM-style mini-EROM wrapper-less cores in scan

This commit modifies bcma_get_next_core() to allow certain wrapper-less
components on systems with a specific mini-erom layout. It resolves a
silent failure where skipped components lead to an empty core list,
eventually causing a null pointer dereference during probe.

> On SoCs that publish a SHIM-style mini-EROM (i.e. BCM6362) the
> WLAN backplane lists three components:
> ChipCommon, IEEE 802.11 and BCMA_CORE_SHIM. None of the three is
> in the existing allowlist, so all three are skipped silently,
> bus->cores stays empty, bcma_find_core(BCMA_CORE_CHIPCOMMON)
> returns NULL, and a later bcma_chipco_watchdog_register()
> dereferences cc->core->bus on its first line and oopses mid-probe.

[Severity: High]
This is a pre-existing issue, but does fixing this specific edge case
leave an underlying structural fragility unhandled?

If a hardware variant genuinely lacks a ChipCommon core or its erom is
malformed, bcma_find_core() returns null and bus->drv_cc.core remains null.

Subsequently, bcma_register_devices() calls bcma_gpio_init() and
bcma_chipco_watchdog_register(). Both of these helper functions
unconditionally dereference cc->core->bus on their first line without
checking if cc->core is valid.

This would trigger a null pointer dereference and a kernel oops mid-probe.
Since the bus can be exposed over hotpluggable pci interfaces, could a
malformed or malicious untrusted device intentionally trigger this local
denial of service?

> diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
> index 983a62ddeebb0..782fc53eb6b3c 100644
> --- a/drivers/bcma/scan.c
> +++ b/drivers/bcma/scan.c
> @@ -318,6 +318,21 @@ static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
>  		case BCMA_CORE_GCI:
>  		/* Not used yet: case BCMA_CORE_OOB_ROUTER: */
>  			break;
> +		case BCMA_CORE_CHIPCOMMON:
> +		case BCMA_CORE_80211:
> +		case BCMA_CORE_SHIM:

[Severity: High]
This isn't a bug introduced by this patch, but does the fallback bridge
check later in bcma_get_next_core() fail to skip the rest of the component's
descriptors before returning -ENXIO?

If a bridge component has master ports, the early bcma_erom_is_bridge()
check returns false. Later, when bcma_erom_get_addr_desc() identifies a
SCAN_ADDR_TYPE_BRIDGE descriptor, it logs "Bridge found" and returns -ENXIO:

drivers/bcma/scan.c:bcma_get_next_core() {
    ...
		/* Try again to see if it is a bridge */
		tmp = bcma_erom_get_addr_desc(bus, eromptr,
					      SCAN_ADDR_TYPE_BRIDGE, 0);
		if (tmp == 0 || IS_ERR_VALUE_U32(tmp)) {
			return -EILSEQ;
		} else {
			bcma_info(bus, "Bridge found\n");
			return -ENXIO;
		}
    ...
}

Crucially, unlike other -ENXIO error paths, it omits calling
bcma_erom_skip_component(bus, eromptr).

If the bridge component has remaining descriptors like additional slave ports
or wrappers, eromptr is left misaligned mid-component. On the subsequent
iteration of the scan loop in bcma_bus_scan(), the parser would expect a
component identifier but encounter a leftover wrapper or port descriptor
instead.

Could this result in an -EILSEQ error that prematurely aborts the entire
bus initialization?

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260529-add-bcm6362-wlan-v1-0-722242777f58@gmail.com?part=2

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 3/4] dt-bindings: bus: add brcm,bcm6362-wlan
  2026-05-29  0:06 ` [PATCH 3/4] dt-bindings: bus: add brcm,bcm6362-wlan Alessio Ferri
@ 2026-05-29  1:36   ` sashiko-bot
  0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-05-29  1:36 UTC (permalink / raw)
  To: Alessio Ferri; +Cc: conor+dt, devicetree, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The child node patternProperty references the meta-schema `/schemas/types.yaml#`, which is invalid for device tree node validation.
--

commit 7510c5aa15726d2bac53841600becc3ad5dfc096
Author: Alessio Ferri <alessio.ferri@mythread.it>

dt-bindings: bus: add brcm,bcm6362-wlan

This commit documents the binding for the SHIM bridge that gates the on-chip
2.4 GHz WLAN block of the Broadcom BCM6362 SoC. It introduces a new YAML
binding for the brcm,bcm6362-wlan device, including a child node for the
bcma AXI backplane.

> diff --git a/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan.yaml b/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan.yaml
> new file mode 100644
> index 0000000000000..c8d49ccdd2c1a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan.yaml

[ ... ]

> +patternProperties:
> +  "^axi@[0-9a-f]+$":
> +    type: object
> +    description: The bcma AXI backplane behind the SHIM.
> +    $ref: /schemas/types.yaml#

[Severity: Low]
Is it correct to reference the meta-schema /schemas/types.yaml# here?

The types.yaml meta-schema provides property type definitions (such as uint32
and phandle) via /definitions/... and is not meant to validate a node's
structure directly. Using it as a schema reference might cause dt-schema
validation to fail or apply meaningless structural constraints during
dt_binding_check.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260529-add-bcm6362-wlan-v1-0-722242777f58@gmail.com?part=3

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH 4/4] bus: add BCM6362 on-chip WLAN SHIM bridge driver
  2026-05-29  0:06 ` [PATCH 4/4] bus: add BCM6362 on-chip WLAN SHIM bridge driver Alessio Ferri
@ 2026-05-29  2:02   ` sashiko-bot
  0 siblings, 0 replies; 9+ messages in thread
From: sashiko-bot @ 2026-05-29  2:02 UTC (permalink / raw)
  To: Alessio Ferri; +Cc: robh, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Low] The `BCM6362_WLAN_SHIM` Kconfig entry selects `BCMA` and `BCMA_HOST_SOC` without inheriting their hardware dependencies (`HAS_IOMEM` and `HAS_DMA`), leading to unmet direct dependency warnings under `COMPILE_TEST`.
--

commit 1aef741e07978e7d0f4c1dd259cf899630d9e65e
Author: Alessio Ferri <alessio.ferri@mythread.it>

bus: add BCM6362 on-chip WLAN SHIM bridge driver

This commit adds a bridge driver to bring up the BCM6362 on-chip WLAN SHIM
block. It configures clocks and toggles resets, then creates a brcm,bus-axi
child platform device for the bcma driver to enumerate.

> diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig
> index 3181d8aa32a3e..e992a34c52308 100644
> --- a/drivers/bus/Kconfig
> +++ b/drivers/bus/Kconfig
> @@ -29,6 +29,19 @@ config ARM_INTEGRATOR_LM
>  	  Say y here to enable support for the ARM Logic Module bus
>  	  found on the ARM Integrator AP (Application Platform)
>  
> +config BCM6362_WLAN_SHIM
> +	tristate "BCM6362 on-chip WLAN SHIM bridge"
> +	depends on BMIPS_GENERIC || COMPILE_TEST
> +	depends on OF
> +	select BCMA
> +	select BCMA_HOST_SOC

[Severity: Low]
Since BCMA depends on HAS_IOMEM and HAS_DMA (via BCMA_POSSIBLE), and
BCMA_HOST_SOC depends on HAS_IOMEM, will selecting them here without
inheriting those hardware dependencies cause unmet direct dependency
warnings?

When COMPILE_TEST is enabled on architectures lacking these capabilities
(such as UML), forcing these symbols on with select might trigger Kconfig
warnings or build failures.

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260529-add-bcm6362-wlan-v1-0-722242777f58@gmail.com?part=4

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-05-29  2:02 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-29  0:05 [PATCH 0/4] bcma: support SHIM-attached big-endian SoC backplanes (BCM6362) Alessio Ferri
2026-05-29  0:05 ` [PATCH 1/4] bcma: support driver specific quirks from soc pdata Alessio Ferri
2026-05-29  0:48   ` sashiko-bot
2026-05-29  0:06 ` [PATCH 2/4] bcma: allow SHIM-style mini-EROM wrapper-less cores in scan Alessio Ferri
2026-05-29  1:25   ` sashiko-bot
2026-05-29  0:06 ` [PATCH 3/4] dt-bindings: bus: add brcm,bcm6362-wlan Alessio Ferri
2026-05-29  1:36   ` sashiko-bot
2026-05-29  0:06 ` [PATCH 4/4] bus: add BCM6362 on-chip WLAN SHIM bridge driver Alessio Ferri
2026-05-29  2:02   ` sashiko-bot

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