Devicetree
 help / color / mirror / Atom feed
* [PATCH v4 0/5] bcma: support the BCM6362 integrated WLAN backplane
@ 2026-11-04 19:30 Alessio Ferri
  2026-11-04 19:30 ` [PATCH v4 1/5] dt-bindings: bus: add Broadcom BCM6362 WLAN AXI backplane Alessio Ferri
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Alessio Ferri @ 2026-11-04 19:30 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Rafał Miłecki, Philipp Zabel, Florian Fainelli,
	Broadcom internal kernel review list, Thomas Bogendoerfer,
	Jonas Gorski
  Cc: linux-wireless, devicetree, linux-kernel, linux-mips,
	Alessio Ferri

The BCM6362 integrates a WLAN macro (802.11n core) on its own 
bcma backplane. The backplane differs from the ones bcma supports 
because: 1) its registers are big-endian, 2) none of its cores has 
a wrapper and make bcma loop crash, and 3) the macro has to be 
clocked, taken out of reset and enabled through a SoC-level WLAN
control block before the backplane can be accessed.

Patches 2 and 3 add two opt-in bus flags to the scan code for the
endianness and for wrapper-less cores. Patch 4 adds a dedicated host
driver that brings the macro up, provides big-endian ops and emulates
the agent registers on top of the WLAN control block. Patches 1 and 5
add the binding and the SoC dtsi node.

My router run with this series backported to kernel 6.12, and has a 
bcm4352 and the integrated wlan targeted by this patch; bcma scans both 
without problems, both chips transmit just fine. The bcm4352 is pcie and
has a normal backplane, so the changes are tested as non-breaking.

This is a small module and i have plenty of hardware to test it (3x 
6362), I am able to maintain it as long as my hardware allows. 
It is also low risk: the flags that change the behaviour of bcma are 
opt-in and it is "complete", at least for the 6362.
Further code is only expected if the bcm63168, that i also have in high 
numbers (5 routers), requires it.

Proof that it scan and works (macs edited):

bcma-sprom bcm6362-sprom: patching SPROM with 38 fixups...
bcma-sprom bcm6362-sprom: mtd mac X
bcma-sprom bcm6362-sprom: registered SPROM for SoC bcma [bus]
bcma-sprom bcm4352-sprom: patching SPROM with 35 fixups...
bcma-sprom bcm4352-sprom: mtd mac X
bcma-sprom bcm4352-sprom: registered SPROM for [1:0]
bcma-host-soc-bcm6362 10004000.bus: bus0: Found chip with id 0x6362, rev 0x01 and package 0x00
bcma-host-soc-bcm6362 10004000.bus: bus0: Core 0 found: ChipCommon (manuf 0x4BF, id 0x800, rev 0x23, class 0x0)
bcma-host-soc-bcm6362 10004000.bus: bus0: Core 1 found: IEEE 802.11 (manuf 0x4BF, id 0x812, rev 0x16, class 0x0)
bcma-host-soc-bcm6362 10004000.bus: bus0: Core 2 found: SHIM (manuf 0x4BF, id 0x837, rev 0x01, class 0x0)
bcma-host-soc-bcm6362 10004000.bus: bus0: Found rev 6 PMU (capabilities 0x084C2806)
bcma-host-soc-bcm6362 10004000.bus: bus0: Flash type not supported
bcma-sprom bcm6362-sprom: requested by SoC bcma [bus]
bcma-host-soc-bcm6362 10004000.bus: bus0: Using SPROM revision 8 provided by platform.
bcma-host-soc-bcm6362 10004000.bus: bus0: PMU res mask pre-write: min=0x0000005d max=0x0000ffff
bcma-host-soc-bcm6362 10004000.bus: bus0: Bus registered
bcma-pci-bridge 0000:01:00.0: enabling device (0000 -> 0002)
bcma-pci-bridge 0000:01:00.0: bus1: Found chip with id 0x4352, rev 0x03 and package 0x01
bcma-pci-bridge 0000:01:00.0: bus1: Core 0 found: ChipCommon (manuf 0x4BF, id 0x800, rev 0x2B, class 0x0)
bcma-pci-bridge 0000:01:00.0: bus1: Core 1 found: IEEE 802.11 (manuf 0x4BF, id 0x812, rev 0x2A, class 0x0)
bcma-pci-bridge 0000:01:00.0: bus1: Core 2 found: ARM CR4 (manuf 0x4BF, id 0x83E, rev 0x02, class 0x0)
bcma-pci-bridge 0000:01:00.0: bus1: Core 3 found: PCIe Gen2 (manuf 0x4BF, id 0x83C, rev 0x01, class 0x0)
bcma-pci-bridge 0000:01:00.0: bus1: Core 4 found: USB 2.0 Device (manuf 0x4BF, id 0x81A, rev 0x11, class 0x0)
bcma-pci-bridge 0000:01:00.0: bus1: Found rev 17 PMU (capabilities 0x10A22B11)
bcma-pci-bridge 0000:01:00.0: bus1: Found SPROM revision 11
bcma-pci-bridge 0000:01:00.0: bus1: PMU PLL pre-write: ctl2=0x00000c31 ctl3=0x0000100e
bcma-pci-bridge 0000:01:00.0: bus1: PMU res mask pre-write: min=0x000007fb max=0x000007ff
bcma-pci-bridge 0000:01:00.0: bus1: Bus registered

br-lan: port 5(phy0-ap0) entered blocking state
br-lan: port 5(phy0-ap0) entered disabled state
b43 bcma0:1 phy0-ap0: entered allmulticast mode
b43 bcma0:1 phy0-ap0: entered promiscuous mode
hostapd: phy0-ap0: interface state UNINITIALIZED->COUNTRY_UPDATE
bcma-host-soc-bcm6362 10004000.bus: bus0: Unknown spuravoidance settings for chip 0x6362, not changing PLL
br-lan: port 5(phy0-ap0) entered blocking state
br-lan: port 5(phy0-ap0) entered forwarding state
netifd: Network device 'phy0-ap0' link is up
hostapd: phy0-ap0: interface state COUNTRY_UPDATE->ENABLED
hostapd: phy0-ap0: AP-ENABLED
hostapd: phy0-ap0: STA Y IEEE 802.11: authenticated
hostapd: phy0-ap0: STA Y IEEE 802.11: associated (aid 1)
hostapd: phy0-ap0: AP-STA-CONNECTED Y auth_alg=open

Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>
---
Changes in v4:
- Incorporated Philipp Zebel suggestion about reset handling
- Link to v3: https://lore.kernel.org/r/20261104-bcm6362-wlan-v3-0-e46562b2ac12@mythread.it

Changes in v3:
- Restricted interrupt mask
- Link to v2: https://lore.kernel.org/r/20261012-bcm6362-wlan-v2-0-4752da7e0982@mythread.it

Changes in v2:
- Replace the drivers/bus bridge driver and the host_soc platform_data
  quirks with a dedicated bcma host driver, drivers/bcma/host_soc_bcm6362.c;
  host_soc.c is left untouched
- DT: describe the WLAN backplane with a single
  "brcm,bcm6362-wlan-bus-axi" node instead of a bridge node with a
  brcm,bus-axi child; add the node to bcm6362.dtsi
- Drop the "SHIM" naming: reg-names "chipcommon"/"wlan-ctrl",
  reset-names "wlan"/"wlan-ubus", bus flag "wrapperless"
- Split the scan changes into two opt-in bus flags (big_endian,
  wrapperless)
- Move the MAINTAINERS entry to the new driver and binding
- Link to v1: https://lore.kernel.org/r/20260529-add-bcm6362-wlan-v1-0-722242777f58@gmail.com

---
Alessio Ferri (5):
      dt-bindings: bus: add Broadcom BCM6362 WLAN AXI backplane
      bcma: scan: support big-endian backplanes
      bcma: scan: accept wrapper-less cores on wrapper-less backplanes
      bcma: add host driver for the BCM6362 integrated WLAN backplane
      MIPS: dts: bcm6362: add the integrated WLAN backplane

 .../bindings/bus/brcm,bcm6362-wlan-bus-axi.yaml    | 109 ++++++
 MAINTAINERS                                        |   7 +
 arch/mips/boot/dts/brcm/bcm6362.dtsi               |  20 +
 drivers/bcma/Kconfig                               |  12 +
 drivers/bcma/Makefile                              |   1 +
 drivers/bcma/bcma_private.h                        |  15 +
 drivers/bcma/host_soc_bcm6362.c                    | 423 +++++++++++++++++++++
 drivers/bcma/main.c                                |   6 +
 drivers/bcma/scan.c                                |  10 +-
 include/linux/bcma/bcma.h                          |   5 +
 10 files changed, 607 insertions(+), 1 deletion(-)
---
base-commit: d6d3455d8751854e0d1820f14184682e23ac4475
change-id: 20261011-bcm6362-wlan-d4473bd1f2e0

Best regards,
-- 
Alessio Ferri <alessio.ferri@mythread.it>


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

* [PATCH v4 1/5] dt-bindings: bus: add Broadcom BCM6362 WLAN AXI backplane
  2026-11-04 19:30 [PATCH v4 0/5] bcma: support the BCM6362 integrated WLAN backplane Alessio Ferri
@ 2026-11-04 19:30 ` Alessio Ferri
  2026-11-04 19:30 ` [PATCH v4 2/5] bcma: scan: support big-endian backplanes Alessio Ferri
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Alessio Ferri @ 2026-11-04 19:30 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Rafał Miłecki, Philipp Zabel, Florian Fainelli,
	Broadcom internal kernel review list, Thomas Bogendoerfer,
	Jonas Gorski
  Cc: linux-wireless, devicetree, linux-kernel, linux-mips,
	Alessio Ferri

The BCM6362 integrates a WLAN macro on its own AXI backplane.
Unlike the backplanes covered by brcm,bus-axi, its cores have no
wrappers: clock gating and reset are driven through a separate
WLAN control register block, and the macro needs a clock, two
resets and the WLAN pads power domain before the backplane can be
accessed. The backplane registers are big-endian.

Add a binding describing the ChipCommon and WLAN control register
blocks, the clock, resets and power domain, and the interrupt-map
used to route core interrupts, following the brcm,bus-axi
convention.

Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>
---
 .../bindings/bus/brcm,bcm6362-wlan-bus-axi.yaml    | 109 +++++++++++++++++++++
 1 file changed, 109 insertions(+)

diff --git a/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan-bus-axi.yaml b/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan-bus-axi.yaml
new file mode 100644
index 000000000000..c27efd719989
--- /dev/null
+++ b/Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan-bus-axi.yaml
@@ -0,0 +1,109 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/bus/brcm,bcm6362-wlan-bus-axi.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Broadcom BCM6362 integrated WLAN AXI backplane
+
+maintainers:
+  - Alessio Ferri <alessio.ferri@mythread.it>
+
+description: |
+  The BCM6362 integrates a WLAN macro on a dedicated AXI backplane
+  (bcma), whose cores are discovered at runtime from the backplane
+  EROM.
+
+  The cores have no DMP wrappers: clock gating and reset of the
+  ChipCommon and 802.11 cores are controlled through a separate WLAN
+  control register block. The backplane registers are big-endian.
+
+  Interrupts of the cores are described with an interrupt-map, as for
+  brcm,bus-axi: bcma looks up each core interrupt with the core base
+  address and the core interrupt index as key. The node has no child
+  nodes; #address-cells only sets the size of the address part of the
+  key.
+
+properties:
+  compatible:
+    const: brcm,bcm6362-wlan-bus-axi
+
+  reg:
+    items:
+      - description: ChipCommon core registers
+      - description: WLAN control registers
+
+  reg-names:
+    items:
+      - const: chipcommon
+      - const: wlan-ctrl
+
+  clocks:
+    maxItems: 1
+
+  resets:
+    items:
+      - description: WLAN macro reset
+      - description: WLAN UBUS interface reset
+
+  reset-names:
+    items:
+      - const: wlan
+      - const: wlan-ubus
+
+  power-domains:
+    maxItems: 1
+
+  "#address-cells":
+    const: 1
+
+  "#interrupt-cells":
+    const: 1
+
+  interrupt-map-mask:
+    items:
+      - const: 0x000fffff
+      - const: 0xffff
+
+  interrupt-map:
+    description:
+      Interrupt of the 802.11 core, keyed by the low 20 bits of the core
+      base address and by the core interrupt index.
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - resets
+  - reset-names
+  - power-domains
+  - "#address-cells"
+  - "#interrupt-cells"
+  - interrupt-map-mask
+  - interrupt-map
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/bcm6362-clock.h>
+    #include <dt-bindings/reset/bcm6362-reset.h>
+    #include <dt-bindings/soc/bcm6362-pm.h>
+
+    bus@10004000 {
+        compatible = "brcm,bcm6362-wlan-bus-axi";
+        reg = <0x10004000 0x1000>, <0x10007000 0x100>;
+        reg-names = "chipcommon", "wlan-ctrl";
+
+        #address-cells = <1>;
+        clocks = <&periph_clk BCM6362_CLK_WLAN_OCP>;
+        #interrupt-cells = <1>;
+        interrupt-map = <0x00005000 0 &periph_intc 7>;
+        interrupt-map-mask = <0x000fffff 0xffff>;
+        power-domains = <&periph_pwr BCM6362_POWER_DOMAIN_WLAN_PADS>;
+        resets = <&periph_rst BCM6362_RST_WLAN_SHIM>,
+                 <&periph_rst BCM6362_RST_WLAN_UBUS>;
+        reset-names = "wlan", "wlan-ubus";
+    };

-- 
2.56.0


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

* [PATCH v4 2/5] bcma: scan: support big-endian backplanes
  2026-11-04 19:30 [PATCH v4 0/5] bcma: support the BCM6362 integrated WLAN backplane Alessio Ferri
  2026-11-04 19:30 ` [PATCH v4 1/5] dt-bindings: bus: add Broadcom BCM6362 WLAN AXI backplane Alessio Ferri
@ 2026-11-04 19:30 ` Alessio Ferri
  2026-11-04 19:30 ` [PATCH v4 3/5] bcma: scan: accept wrapper-less cores on wrapper-less backplanes Alessio Ferri
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Alessio Ferri @ 2026-11-04 19:30 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Rafał Miłecki, Philipp Zabel, Florian Fainelli,
	Broadcom internal kernel review list, Thomas Bogendoerfer,
	Jonas Gorski
  Cc: linux-wireless, devicetree, linux-kernel, linux-mips,
	Alessio Ferri

On some SoCs the bcma backplane is a big-endian peripheral, so the
ChipCommon ID/EROM pointer registers and the EROM itself read wrong
 with readl().

Add a big_endian flag to struct bcma_bus, set by the host driver
before bcma_init_bus(), and use ioread32be() for scan-time accesses
when it is set. Core register accesses after the scan already go
through the host ops, which the host driver provides with the right
endianness.

Nothing changes for other devices.

Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>
---
 drivers/bcma/scan.c       | 4 +++-
 include/linux/bcma/bcma.h | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

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 17fc50190014..7ab2b21e7238 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -362,6 +362,9 @@ 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;
+
+	/* Backplane registers, EROM included, are big-endian */
+	bool big_endian;
 };
 
 static inline u32 bcma_read8(struct bcma_device *core, u16 offset)

-- 
2.56.0


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

* [PATCH v4 3/5] bcma: scan: accept wrapper-less cores on wrapper-less backplanes
  2026-11-04 19:30 [PATCH v4 0/5] bcma: support the BCM6362 integrated WLAN backplane Alessio Ferri
  2026-11-04 19:30 ` [PATCH v4 1/5] dt-bindings: bus: add Broadcom BCM6362 WLAN AXI backplane Alessio Ferri
  2026-11-04 19:30 ` [PATCH v4 2/5] bcma: scan: support big-endian backplanes Alessio Ferri
@ 2026-11-04 19:30 ` Alessio Ferri
  2026-11-04 19:30 ` [PATCH v4 4/5] bcma: add host driver for the BCM6362 integrated WLAN backplane Alessio Ferri
  2026-11-04 19:30 ` [PATCH v4 5/5] MIPS: dts: bcm6362: add the " Alessio Ferri
  4 siblings, 0 replies; 7+ messages in thread
From: Alessio Ferri @ 2026-11-04 19:30 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Rafał Miłecki, Philipp Zabel, Florian Fainelli,
	Broadcom internal kernel review list, Thomas Bogendoerfer,
	Jonas Gorski
  Cc: linux-wireless, devicetree, linux-kernel, linux-mips,
	Alessio Ferri

The scan drops every component that publishes no master or slave
wrapper in the EROM (NMW = NSW = 0), apart from a few known cores,
because without a wrapper bcma has no agent registers to gate and
crash. Since usually bcma is loaded early, it ends as a loop-crash.

Some backplanes, such as the integrated WLAN of the BCM6362, have
no wrappers on any core. ChipCommon and the 802.11 core are gated
through a SoC-level register block owned by the host driver, whose
aread32/awrite32 ops emulate the agent registers, and core 0x837
needs no gating.

Add a wrapperless flag to struct bcma_bus, set by the host driver
before bcma_init_bus(), and accept these cores without wrappers when
it is set. Other hosts keep rejecting them.

Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>
---
 drivers/bcma/scan.c       | 6 ++++++
 include/linux/bcma/bcma.h | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/drivers/bcma/scan.c b/drivers/bcma/scan.c
index 983a62ddeebb..ef880b635971 100644
--- a/drivers/bcma/scan.c
+++ b/drivers/bcma/scan.c
@@ -318,6 +318,12 @@ 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:
+			if (bus->wrapperless)
+				break;
+			fallthrough;
 		default:
 			bcma_erom_skip_component(bus, eromptr);
 			return -ENXIO;
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 7ab2b21e7238..5dcf877e2872 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -365,6 +365,8 @@ struct bcma_bus {
 
 	/* Backplane registers, EROM included, are big-endian */
 	bool big_endian;
+	/* Cores have no DMP wrappers, the host ops handle agent accesses */
+	bool wrapperless;
 };
 
 static inline u32 bcma_read8(struct bcma_device *core, u16 offset)

-- 
2.56.0


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

* [PATCH v4 4/5] bcma: add host driver for the BCM6362 integrated WLAN backplane
  2026-11-04 19:30 [PATCH v4 0/5] bcma: support the BCM6362 integrated WLAN backplane Alessio Ferri
                   ` (2 preceding siblings ...)
  2026-11-04 19:30 ` [PATCH v4 3/5] bcma: scan: accept wrapper-less cores on wrapper-less backplanes Alessio Ferri
@ 2026-11-04 19:30 ` Alessio Ferri
  2026-11-04 20:07   ` sashiko-bot
  2026-11-04 19:30 ` [PATCH v4 5/5] MIPS: dts: bcm6362: add the " Alessio Ferri
  4 siblings, 1 reply; 7+ messages in thread
From: Alessio Ferri @ 2026-11-04 19:30 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Rafał Miłecki, Philipp Zabel, Florian Fainelli,
	Broadcom internal kernel review list, Thomas Bogendoerfer,
	Jonas Gorski
  Cc: linux-wireless, devicetree, linux-kernel, linux-mips,
	Alessio Ferri

The BCM6362 integrates a WLAN macro on a dedicated bcma backplane.
CFE leaves the macro clock gated and in reset, the backplane is
a big-endian peripheral, and none of the cores has a wrapper:
gating and reset of ChipCommon and of the 802.11 core go through
per-core control registers in a separate WLAN control block.

Add a host driver for it that:

  - maps the ChipCommon and WLAN control register blocks;
  - enables the clock, cycles the WLAN and WLAN UBUS resets and runs the
    macro enable sequence before bcma touches the backplane;
  - provides big-endian register and block I/O ops;
  - emulates BCMA_IOCTL, BCMA_IOST, BCMA_RESET_CTL and BCMA_RESET_ST
    on top of the per-core control registers. The PHY bits of
    BCMA_IOST report what b43 expect;
  - sets the big_endian and wrapperless bus flags before scanning.

The macro enable sequence comes from the bcm6362 platform setup
code.

As for the PCI and generic SoC hosts, the driver is linked into
bcma.ko and registered from bcma_modinit().

Add a MAINTAINERS entry for the driver and its binding.

The 802.11 core (rev 0x16) is handled by b43 once a SPROM is
available; on this SoC it is not stored on the chip and has to be
provided. In openwrt i use 6362-sprom plus fixups.

Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>
---
 MAINTAINERS                     |   7 +
 drivers/bcma/Kconfig            |  12 ++
 drivers/bcma/Makefile           |   1 +
 drivers/bcma/bcma_private.h     |  15 ++
 drivers/bcma/host_soc_bcm6362.c | 423 ++++++++++++++++++++++++++++++++++++++++
 drivers/bcma/main.c             |   6 +
 6 files changed, 464 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index f53047aa8d3c..00d964829db5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5235,6 +5235,13 @@ S:	Maintained
 F:	arch/arm/boot/dts/broadcom/bcm47189*
 F:	arch/arm/boot/dts/broadcom/bcm53573*
 
+BROADCOM BCM6362 WLAN BCMA HOST DRIVER
+M:	Alessio Ferri <alessio.ferri@mythread.it>
+L:	linux-wireless@vger.kernel.org
+S:	Maintained
+F:	Documentation/devicetree/bindings/bus/brcm,bcm6362-wlan-bus-axi.yaml
+F:	drivers/bcma/host_soc_bcm6362.c
+
 BROADCOM BCM63XX/BCM33XX UDC DRIVER
 M:	Kevin Cernekee <cernekee@gmail.com>
 L:	linux-usb@vger.kernel.org
diff --git a/drivers/bcma/Kconfig b/drivers/bcma/Kconfig
index b9558ff20830..ef0c461bdf90 100644
--- a/drivers/bcma/Kconfig
+++ b/drivers/bcma/Kconfig
@@ -38,6 +38,18 @@ config BCMA_HOST_SOC
 
 	  If unsure, say N
 
+config BCMA_HOST_SOC_BCM6362
+	bool "Support for the BCM6362 integrated WLAN backplane"
+	depends on BMIPS_GENERIC || COMPILE_TEST
+	depends on OF
+	help
+	  Host driver for the bcma backplane of the WLAN macro
+	  integrated in the Broadcom BCM6362 SoC. It powers the macro on
+	  and lets bcma enumerate the backplane, so that the 802.11 core
+	  can be driven by b43.
+
+	  If unsure, say N
+
 config BCMA_DRIVER_PCI
 	bool "BCMA Broadcom PCI core driver"
 	depends on PCI
diff --git a/drivers/bcma/Makefile b/drivers/bcma/Makefile
index f8c37de35da2..3ff93990ecbb 100644
--- a/drivers/bcma/Makefile
+++ b/drivers/bcma/Makefile
@@ -13,6 +13,7 @@ bcma-$(CONFIG_BCMA_DRIVER_GMAC_CMN)	+= driver_gmac_cmn.o
 bcma-$(CONFIG_BCMA_DRIVER_GPIO)		+= driver_gpio.o
 bcma-$(CONFIG_BCMA_HOST_PCI)		+= host_pci.o
 bcma-$(CONFIG_BCMA_HOST_SOC)		+= host_soc.o
+bcma-$(CONFIG_BCMA_HOST_SOC_BCM6362)	+= host_soc_bcm6362.o
 obj-$(CONFIG_BCMA)			+= bcma.o
 
 ccflags-$(CONFIG_BCMA_DEBUG)		:= -DDEBUG
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 6eded32d1aac..931a0ca0aea3 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -118,6 +118,21 @@ static inline void __exit bcma_host_soc_unregister_driver(void)
 }
 #endif /* CONFIG_BCMA_HOST_SOC && CONFIG_OF */
 
+/* host_soc_bcm6362.c */
+#ifdef CONFIG_BCMA_HOST_SOC_BCM6362
+int __init bcma_host_soc_bcm6362_register_driver(void);
+void __exit bcma_host_soc_bcm6362_unregister_driver(void);
+#else
+static inline int __init bcma_host_soc_bcm6362_register_driver(void)
+{
+	return 0;
+}
+
+static inline void __exit bcma_host_soc_bcm6362_unregister_driver(void)
+{
+}
+#endif /* CONFIG_BCMA_HOST_SOC_BCM6362 */
+
 /* driver_pci.c */
 #ifdef CONFIG_BCMA_DRIVER_PCI
 u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
diff --git a/drivers/bcma/host_soc_bcm6362.c b/drivers/bcma/host_soc_bcm6362.c
new file mode 100644
index 000000000000..e8400cb62448
--- /dev/null
+++ b/drivers/bcma/host_soc_bcm6362.c
@@ -0,0 +1,423 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Broadcom BCM6362 integrated WLAN backplane host driver
+ *
+ * The backplane is a big-endian peripheral. Its cores have no DMP
+ * wrappers: the agent registers of ChipCommon and of the 802.11 core
+ * are emulated on top of the per-core control registers of the WLAN
+ * control block.
+ */
+
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+#include <linux/slab.h>
+
+#include <linux/bcma/bcma.h>
+
+#include "bcma_private.h"
+
+#define BCM6362_WLAN_MISC			0x00
+#define  BCM6362_WLAN_MISC_FORCE_CLK_ON		BIT(2)
+#define  BCM6362_WLAN_MISC_MACRO_DISABLE	BIT(1)
+#define  BCM6362_WLAN_MISC_MACRO_SOFT_RESET	BIT(0)
+#define BCM6362_WLAN_CC_CONTROL			0x08
+#define BCM6362_WLAN_MAC_CONTROL		0x10
+#define BCM6362_WLAN_CC_ID_A			0x18
+#define BCM6362_WLAN_MAC_ID_A			0x24
+
+/*
+ * Per-core control register layout: BCMA_IOCTL in the low 16 bits,
+ * BCMA_RESET_CTL_RESET in bit 16.
+ */
+#define BCM6362_WLAN_CTL_IOCTL			GENMASK(15, 0)
+#define BCM6362_WLAN_CTL_RESET			BIT(16)
+
+#define BCM6362_WLAN_IOST_2G_PHY		BIT(0)
+#define BCM6362_WLAN_IOST_5G_PHY		BIT(1)
+
+struct bcma_host_soc_bcm6362 {
+	struct bcma_bus		bus;
+	void __iomem		*wlan_ctrl;
+	struct clk		*clk;
+	struct reset_control_bulk_data resets[2];
+};
+
+static struct bcma_host_soc_bcm6362 *to_bcm6362(struct bcma_bus *bus)
+{
+	return container_of(bus, struct bcma_host_soc_bcm6362, bus);
+}
+
+static u8 bcma_host_soc_bcm6362_read8(struct bcma_device *core, u16 offset)
+{
+	return readb(core->io_addr + offset);
+}
+
+static u16 bcma_host_soc_bcm6362_read16(struct bcma_device *core, u16 offset)
+{
+	return ioread16be(core->io_addr + offset);
+}
+
+static u32 bcma_host_soc_bcm6362_read32(struct bcma_device *core, u16 offset)
+{
+	return ioread32be(core->io_addr + offset);
+}
+
+static void bcma_host_soc_bcm6362_write8(struct bcma_device *core, u16 offset,
+					 u8 value)
+{
+	writeb(value, core->io_addr + offset);
+}
+
+static void bcma_host_soc_bcm6362_write16(struct bcma_device *core, u16 offset,
+					  u16 value)
+{
+	iowrite16be(value, core->io_addr + offset);
+}
+
+static void bcma_host_soc_bcm6362_write32(struct bcma_device *core, u16 offset,
+					  u32 value)
+{
+	iowrite32be(value, core->io_addr + offset);
+}
+
+#ifdef CONFIG_BCMA_BLOCKIO
+/* Buffers are kept in bus byte order, so copy them without swapping. */
+static void bcma_host_soc_bcm6362_block_read(struct bcma_device *core,
+					     void *buffer, size_t count,
+					     u16 offset, u8 reg_width)
+{
+	void __iomem *addr = core->io_addr + offset;
+
+	switch (reg_width) {
+	case sizeof(u8): {
+		u8 *buf = buffer;
+
+		while (count) {
+			*buf = __raw_readb(addr);
+			buf++;
+			count--;
+		}
+		break;
+	}
+	case sizeof(u16): {
+		__be16 *buf = buffer;
+
+		WARN_ON(count & 1);
+		while (count) {
+			*buf = (__force __be16)__raw_readw(addr);
+			buf++;
+			count -= 2;
+		}
+		break;
+	}
+	case sizeof(u32): {
+		__be32 *buf = buffer;
+
+		WARN_ON(count & 3);
+		while (count) {
+			*buf = (__force __be32)__raw_readl(addr);
+			buf++;
+			count -= 4;
+		}
+		break;
+	}
+	default:
+		WARN_ON(1);
+	}
+}
+
+static void bcma_host_soc_bcm6362_block_write(struct bcma_device *core,
+					      const void *buffer, size_t count,
+					      u16 offset, u8 reg_width)
+{
+	void __iomem *addr = core->io_addr + offset;
+
+	switch (reg_width) {
+	case sizeof(u8): {
+		const u8 *buf = buffer;
+
+		while (count) {
+			__raw_writeb(*buf, addr);
+			buf++;
+			count--;
+		}
+		break;
+	}
+	case sizeof(u16): {
+		const __be16 *buf = buffer;
+
+		WARN_ON(count & 1);
+		while (count) {
+			__raw_writew((__force u16)*buf, addr);
+			buf++;
+			count -= 2;
+		}
+		break;
+	}
+	case sizeof(u32): {
+		const __be32 *buf = buffer;
+
+		WARN_ON(count & 3);
+		while (count) {
+			__raw_writel((__force u32)*buf, addr);
+			buf++;
+			count -= 4;
+		}
+		break;
+	}
+	default:
+		WARN_ON(1);
+	}
+}
+#endif /* CONFIG_BCMA_BLOCKIO */
+
+static void __iomem *bcma_host_soc_bcm6362_ctl_reg(struct bcma_device *core)
+{
+	struct bcma_host_soc_bcm6362 *host = to_bcm6362(core->bus);
+
+	switch (core->id.id) {
+	case BCMA_CORE_CHIPCOMMON:
+		return host->wlan_ctrl + BCM6362_WLAN_CC_CONTROL;
+	case BCMA_CORE_80211:
+		return host->wlan_ctrl + BCM6362_WLAN_MAC_CONTROL;
+	default:
+		return NULL;
+	}
+}
+
+static u32 bcma_host_soc_bcm6362_aread32(struct bcma_device *core, u16 offset)
+{
+	void __iomem *ctl = bcma_host_soc_bcm6362_ctl_reg(core);
+
+	switch (offset) {
+	case BCMA_IOCTL:
+		if (!ctl)
+			return BCMA_IOCTL_CLK;
+		return ioread32be(ctl) & BCM6362_WLAN_CTL_IOCTL;
+	case BCMA_IOST:
+		/*
+		 * The core bits of MacStatus do not reflect the PHY while
+		 * the 802.11 core is held in reset, so report what the
+		 * macro supports: a dual-band PHY and 64-bit DMA. The bands
+		 * actually usable depend on the board antennas.
+		 */
+		if (core->id.id == BCMA_CORE_80211)
+			return BCM6362_WLAN_IOST_2G_PHY |
+			       BCM6362_WLAN_IOST_5G_PHY | BCMA_IOST_DMA64;
+		return 0;
+	case BCMA_RESET_CTL:
+		if (ctl && (ioread32be(ctl) & BCM6362_WLAN_CTL_RESET))
+			return BCMA_RESET_CTL_RESET;
+		return 0;
+	case BCMA_RESET_ST:
+		return 0;
+	default:
+		dev_warn_once(core->bus->dev,
+			      "core 0x%03x: unhandled agent read at 0x%03x\n",
+			      core->id.id, offset);
+		return 0;
+	}
+}
+
+static void bcma_host_soc_bcm6362_awrite32(struct bcma_device *core, u16 offset,
+					   u32 value)
+{
+	void __iomem *ctl = bcma_host_soc_bcm6362_ctl_reg(core);
+	u32 val;
+
+	if (!ctl)
+		goto unhandled;
+
+	switch (offset) {
+	case BCMA_IOCTL:
+		val = ioread32be(ctl) & BCM6362_WLAN_CTL_RESET;
+		val |= value & BCM6362_WLAN_CTL_IOCTL;
+		iowrite32be(val, ctl);
+		return;
+	case BCMA_RESET_CTL:
+		val = ioread32be(ctl);
+		if (value & BCMA_RESET_CTL_RESET)
+			val |= BCM6362_WLAN_CTL_RESET;
+		else
+			val &= ~BCM6362_WLAN_CTL_RESET;
+		iowrite32be(val, ctl);
+		return;
+	}
+
+unhandled:
+	dev_warn_once(core->bus->dev,
+		      "core 0x%03x: unhandled agent write 0x%08x at 0x%03x\n",
+		      core->id.id, value, offset);
+}
+
+static const struct bcma_host_ops bcma_host_soc_bcm6362_ops = {
+	.read8		= bcma_host_soc_bcm6362_read8,
+	.read16		= bcma_host_soc_bcm6362_read16,
+	.read32		= bcma_host_soc_bcm6362_read32,
+	.write8		= bcma_host_soc_bcm6362_write8,
+	.write16	= bcma_host_soc_bcm6362_write16,
+	.write32	= bcma_host_soc_bcm6362_write32,
+#ifdef CONFIG_BCMA_BLOCKIO
+	.block_read	= bcma_host_soc_bcm6362_block_read,
+	.block_write	= bcma_host_soc_bcm6362_block_write,
+#endif
+	.aread32	= bcma_host_soc_bcm6362_aread32,
+	.awrite32	= bcma_host_soc_bcm6362_awrite32,
+};
+
+/*
+ * Macro enable sequence from the Broadcom board support code: with the
+ * clock forced on and the macro in soft reset, enable the 802.11 core
+ * clock with force gated clock set, then release the soft reset and the
+ * forces.
+ */
+static int bcma_host_soc_bcm6362_power_on(struct bcma_host_soc_bcm6362 *host)
+{
+	void __iomem *base = host->wlan_ctrl;
+	int err;
+
+	err = clk_prepare_enable(host->clk);
+	if (err) {
+		dev_err(host->bus.dev, "failed to enable clock: %d\n", err);
+		return err;
+	}
+	fsleep(10000);
+
+	err = reset_control_bulk_assert(ARRAY_SIZE(host->resets), host->resets);
+	if (err)
+		goto err_resets;
+	fsleep(1000);
+	err = reset_control_bulk_deassert(ARRAY_SIZE(host->resets), host->resets);
+	if (err)
+		goto err_resets;
+	fsleep(1000);
+
+	iowrite32be(BCM6362_WLAN_MISC_FORCE_CLK_ON |
+		    BCM6362_WLAN_MISC_MACRO_SOFT_RESET,
+		    base + BCM6362_WLAN_MISC);
+	fsleep(1000);
+
+	iowrite32be(BCMA_IOCTL_FGC | BCMA_IOCTL_CLK,
+		    base + BCM6362_WLAN_MAC_CONTROL);
+	iowrite32be(BCM6362_WLAN_MISC_FORCE_CLK_ON, base + BCM6362_WLAN_MISC);
+	iowrite32be(0, base + BCM6362_WLAN_MISC);
+	iowrite32be(BCMA_IOCTL_CLK, base + BCM6362_WLAN_MAC_CONTROL);
+
+	dev_dbg(host->bus.dev, "CC ID A 0x%08x, MAC ID A 0x%08x\n",
+		ioread32be(base + BCM6362_WLAN_CC_ID_A),
+		ioread32be(base + BCM6362_WLAN_MAC_ID_A));
+
+	return 0;
+
+err_resets:
+	dev_err(host->bus.dev, "failed to cycle resets: %d\n", err);
+	clk_disable_unprepare(host->clk);
+	return err;
+}
+
+static void bcma_host_soc_bcm6362_power_off(struct bcma_host_soc_bcm6362 *host)
+{
+	void __iomem *base = host->wlan_ctrl;
+
+	iowrite32be(0, base + BCM6362_WLAN_MAC_CONTROL);
+	iowrite32be(BCM6362_WLAN_MISC_MACRO_DISABLE |
+		    BCM6362_WLAN_MISC_MACRO_SOFT_RESET,
+		    base + BCM6362_WLAN_MISC);
+	reset_control_bulk_assert(ARRAY_SIZE(host->resets), host->resets);
+	clk_disable_unprepare(host->clk);
+}
+
+static int bcma_host_soc_bcm6362_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct bcma_host_soc_bcm6362 *host;
+	struct bcma_bus *bus;
+	int err;
+
+	host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
+	if (!host)
+		return -ENOMEM;
+
+	bus = &host->bus;
+	bus->dev = dev;
+
+	bus->mmio = devm_platform_ioremap_resource_byname(pdev, "chipcommon");
+	if (IS_ERR(bus->mmio))
+		return PTR_ERR(bus->mmio);
+
+	host->wlan_ctrl = devm_platform_ioremap_resource_byname(pdev, "wlan-ctrl");
+	if (IS_ERR(host->wlan_ctrl))
+		return PTR_ERR(host->wlan_ctrl);
+
+	host->clk = devm_clk_get(dev, NULL);
+	if (IS_ERR(host->clk))
+		return dev_err_probe(dev, PTR_ERR(host->clk),
+				     "failed to get clock\n");
+
+	host->resets[0].id = "wlan";
+	host->resets[1].id = "wlan-ubus";
+	err = devm_reset_control_bulk_get_exclusive(dev, ARRAY_SIZE(host->resets),
+						    host->resets);
+	if (err)
+		return dev_err_probe(dev, err, "failed to get resets\n");
+
+	err = bcma_host_soc_bcm6362_power_on(host);
+	if (err)
+		return err;
+
+	bus->hosttype = BCMA_HOSTTYPE_SOC;
+	bus->ops = &bcma_host_soc_bcm6362_ops;
+	bus->big_endian = true;
+	bus->wrapperless = true;
+
+	bcma_init_bus(bus);
+
+	err = bcma_bus_register(bus);
+	if (err) {
+		bcma_host_soc_bcm6362_power_off(host);
+		return err;
+	}
+
+	platform_set_drvdata(pdev, host);
+
+	return 0;
+}
+
+static void bcma_host_soc_bcm6362_remove(struct platform_device *pdev)
+{
+	struct bcma_host_soc_bcm6362 *host = platform_get_drvdata(pdev);
+
+	bcma_bus_unregister(&host->bus);
+	bcma_host_soc_bcm6362_power_off(host);
+}
+
+static const struct of_device_id bcma_host_soc_bcm6362_of_match[] = {
+	{ .compatible = "brcm,bcm6362-wlan-bus-axi" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, bcma_host_soc_bcm6362_of_match);
+
+static struct platform_driver bcma_host_soc_bcm6362_driver = {
+	.driver = {
+		.name = "bcma-host-soc-bcm6362",
+		.of_match_table = bcma_host_soc_bcm6362_of_match,
+	},
+	.probe		= bcma_host_soc_bcm6362_probe,
+	.remove		= bcma_host_soc_bcm6362_remove,
+};
+
+int __init bcma_host_soc_bcm6362_register_driver(void)
+{
+	return platform_driver_register(&bcma_host_soc_bcm6362_driver);
+}
+
+void __exit bcma_host_soc_bcm6362_unregister_driver(void)
+{
+	platform_driver_unregister(&bcma_host_soc_bcm6362_driver);
+}
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index 72f045e6ed51..4ccc9fb98f61 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -682,6 +682,11 @@ static int __init bcma_modinit(void)
 		pr_err("SoC host initialization failed\n");
 		err = 0;
 	}
+	err = bcma_host_soc_bcm6362_register_driver();
+	if (err) {
+		pr_err("BCM6362 WLAN host initialization failed\n");
+		err = 0;
+	}
 #ifdef CONFIG_BCMA_HOST_PCI
 	err = bcma_host_pci_init();
 	if (err) {
@@ -699,6 +704,7 @@ static void __exit bcma_modexit(void)
 #ifdef CONFIG_BCMA_HOST_PCI
 	bcma_host_pci_exit();
 #endif
+	bcma_host_soc_bcm6362_unregister_driver();
 	bcma_host_soc_unregister_driver();
 	bus_unregister(&bcma_bus_type);
 }

-- 
2.56.0


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

* [PATCH v4 5/5] MIPS: dts: bcm6362: add the integrated WLAN backplane
  2026-11-04 19:30 [PATCH v4 0/5] bcma: support the BCM6362 integrated WLAN backplane Alessio Ferri
                   ` (3 preceding siblings ...)
  2026-11-04 19:30 ` [PATCH v4 4/5] bcma: add host driver for the BCM6362 integrated WLAN backplane Alessio Ferri
@ 2026-11-04 19:30 ` Alessio Ferri
  4 siblings, 0 replies; 7+ messages in thread
From: Alessio Ferri @ 2026-11-04 19:30 UTC (permalink / raw)
  To: Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Rafał Miłecki, Philipp Zabel, Florian Fainelli,
	Broadcom internal kernel review list, Thomas Bogendoerfer,
	Jonas Gorski
  Cc: linux-wireless, devicetree, linux-kernel, linux-mips,
	Alessio Ferri

Describe the bcma backplane of the integrated WLAN macro,
with its clock, resets, power domain and the interrupt of the 802.11
core. It is default disabled, boards having the WLAN need to
enable it.

Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Signed-off-by: Alessio Ferri <alessio.ferri@mythread.it>
---
 arch/mips/boot/dts/brcm/bcm6362.dtsi | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/arch/mips/boot/dts/brcm/bcm6362.dtsi b/arch/mips/boot/dts/brcm/bcm6362.dtsi
index d74021925c53..c6de39588840 100644
--- a/arch/mips/boot/dts/brcm/bcm6362.dtsi
+++ b/arch/mips/boot/dts/brcm/bcm6362.dtsi
@@ -261,5 +261,25 @@ usbh: usb-phy@10002700 {
 
 			status = "disabled";
 		};
+
+		wlan: bus@10004000 {
+			compatible = "brcm,bcm6362-wlan-bus-axi";
+			reg = <0x10004000 0x1000>,
+			      <0x10007000 0x100>;
+			reg-names = "chipcommon", "wlan-ctrl";
+
+			#address-cells = <1>;
+			clocks = <&periph_clk BCM6362_CLK_WLAN_OCP>;
+			#interrupt-cells = <1>;
+			interrupt-map = <0x00005000 0 &periph_intc 7>;
+			interrupt-map-mask = <0x000fffff 0xffff>;
+			power-domains =
+				<&periph_pwr BCM6362_POWER_DOMAIN_WLAN_PADS>;
+			resets = <&periph_rst BCM6362_RST_WLAN_SHIM>,
+				 <&periph_rst BCM6362_RST_WLAN_UBUS>;
+			reset-names = "wlan", "wlan-ubus";
+
+			status = "disabled";
+		};
 	};
 };

-- 
2.56.0


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

* Re: [PATCH v4 4/5] bcma: add host driver for the BCM6362 integrated WLAN backplane
  2026-11-04 19:30 ` [PATCH v4 4/5] bcma: add host driver for the BCM6362 integrated WLAN backplane Alessio Ferri
@ 2026-11-04 20:07   ` sashiko-bot
  0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-11-04 20:07 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:
- [Medium] bcma: unconditional driver unregister in bcma_modexit() after init failure
- [Medium] bcma: memory and iomap leak in bcma_host_soc_bcm6362_probe() on scan error
--

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

bcma: add host driver for the BCM6362 integrated WLAN backplane

This commit adds a host driver for the BCM6362 integrated WLAN bcma
backplane, handling clock enablement, resets, big-endian I/O ops, and
emulation of per-core control registers for wrapperless cores.

> diff --git a/drivers/bcma/host_soc_bcm6362.c b/drivers/bcma/host_soc_bcm6362.c
> new file mode 100644
> index 0000000000000..e8400cb624484
> --- /dev/null
> +++ b/drivers/bcma/host_soc_bcm6362.c
[ ... ]
> +static int bcma_host_soc_bcm6362_probe(struct platform_device *pdev)
> +{
[ ... ]
> +	err = bcma_bus_register(bus);
> +	if (err) {
> +		bcma_host_soc_bcm6362_power_off(host);
> +		return err;
> +	}

[Severity: Medium]
As reported by Sashiko on v2 [1], does bcma_host_soc_bcm6362_probe() leak
core structures and their ioremap() mappings if bcma_bus_register() fails?

When bcma_bus_register() calls bcma_bus_scan(), each discovered core is
allocated, mapped via ioremap() into core->io_addr, and appended to
bus->cores. If scanning a subsequent core fails (for example, returning
-ENOMEM or -EILSEQ in bcma_bus_scan()), bcma_bus_scan() returns the error
with any previously scanned cores still on bus->cores:

drivers/bcma/scan.c:bcma_bus_scan() {
    ...
		err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
		if (err < 0) {
			kfree(core);
			...
			goto out;
		}
    ...
}

Because bcma_host_soc_bcm6362_probe() powers off and returns without
calling bcma_unregister_cores(bus), wouldn't those allocated cores and
their core->io_addr mappings be leaked?

> diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
> index 72f045e6ed513..4ccc9fb98f616 100644
> --- a/drivers/bcma/main.c
> +++ b/drivers/bcma/main.c
> @@ -682,6 +682,11 @@ static int __init bcma_modinit(void)
>  		pr_err("SoC host initialization failed\n");
>  		err = 0;
>  	}
> +	err = bcma_host_soc_bcm6362_register_driver();
> +	if (err) {
> +		pr_err("BCM6362 WLAN host initialization failed\n");
> +		err = 0;
> +	}
>  #ifdef CONFIG_BCMA_HOST_PCI
>  	err = bcma_host_pci_init();
>  	if (err) {
> @@ -699,6 +704,7 @@ static void __exit bcma_modexit(void)
>  #ifdef CONFIG_BCMA_HOST_PCI
>  	bcma_host_pci_exit();
>  #endif
> +	bcma_host_soc_bcm6362_unregister_driver();

[Severity: Medium]
As reported by Sashiko on v2 [1], could calling
bcma_host_soc_bcm6362_unregister_driver() unconditionally in bcma_modexit()
trigger a warning if registration failed during module init?

In bcma_modinit(), if bcma_host_soc_bcm6362_register_driver() fails, the
error is logged and cleared to 0 so the module still loads, leaving
bcma_host_soc_bcm6362_driver.driver.p as NULL. When the module is later
unloaded, bcma_modexit() calls:

bcma_host_soc_bcm6362_unregister_driver()
  -> platform_driver_unregister()
    -> driver_unregister()

which checks if (!drv || !drv->p) and hits WARN(1, "Unexpected driver
unregister!\n").

[1] https://lore.kernel.org/r/20261012-bcm6362-wlan-v2-4-4752da7e0982@mythread.it

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261104-bcm6362-wlan-v4-0-f001f6d75dc3@mythread.it?part=4

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

end of thread, other threads:[~2026-11-04 20:07 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-04 19:30 [PATCH v4 0/5] bcma: support the BCM6362 integrated WLAN backplane Alessio Ferri
2026-11-04 19:30 ` [PATCH v4 1/5] dt-bindings: bus: add Broadcom BCM6362 WLAN AXI backplane Alessio Ferri
2026-11-04 19:30 ` [PATCH v4 2/5] bcma: scan: support big-endian backplanes Alessio Ferri
2026-11-04 19:30 ` [PATCH v4 3/5] bcma: scan: accept wrapper-less cores on wrapper-less backplanes Alessio Ferri
2026-11-04 19:30 ` [PATCH v4 4/5] bcma: add host driver for the BCM6362 integrated WLAN backplane Alessio Ferri
2026-11-04 20:07   ` sashiko-bot
2026-11-04 19:30 ` [PATCH v4 5/5] MIPS: dts: bcm6362: add the " Alessio Ferri

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