Re: [PATCH v3 4/5] bcma: add host driver for the BCM6362 integrated WLAN backplane
From: Philipp Zabel
Date: Wed Nov 04 2026 - 04:59:09 EST
On Mi, 2026-11-04 at 00:31 +0100, Alessio Ferri wrote:
> 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 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 needs to hear;
> - sets the big_endian and wrapperless bus flags before scanning.
>
> 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.
>
> Signed-off-by: Alessio Ferri <alessio.ferri@xxxxxxxxxxx>
> ---
> MAINTAINERS | 7 +
> drivers/bcma/Kconfig | 12 ++
> drivers/bcma/Makefile | 1 +
> drivers/bcma/bcma_private.h | 15 ++
> drivers/bcma/host_soc_bcm6362.c | 419 ++++++++++++++++++++++++++++++++++++++++
> drivers/bcma/main.c | 6 +
> 6 files changed, 460 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@xxxxxxxxxxx>
> +L: linux-wireless@xxxxxxxxxxxxxxx
> +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@xxxxxxxxx>
> L: linux-usb@xxxxxxxxxxxxxxx
> 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..5a4fa6a63411
> --- /dev/null
> +++ b/drivers/bcma/host_soc_bcm6362.c
> @@ -0,0 +1,419 @@
[...]
> +struct bcma_host_soc_bcm6362 {
[...]
> + struct reset_control *rst_wlan;
> + struct reset_control *rst_wlan_ubus;
> +};
[...]
> +/*
> + * 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)
> +{
[...]
> + reset_control_assert(host->rst_wlan_ubus);
> + reset_control_assert(host->rst_wlan);
These are asserted in different order than in
bcma_host_soc_bcm6362_power_off(). Is this on purpose?
If the order can be switched here, you can use the reset_control_bulk
API.
> + fsleep(1000);
> + reset_control_deassert(host->rst_wlan_ubus);
> + reset_control_deassert(host->rst_wlan);
> + fsleep(1000);
[...]
> +}
> +
> +static void bcma_host_soc_bcm6362_power_off(struct bcma_host_soc_bcm6362 *host)
> +{
[...]
> + reset_control_assert(host->rst_wlan);
> + reset_control_assert(host->rst_wlan_ubus);
[...]
> +static int bcma_host_soc_bcm6362_probe(struct platform_device *pdev)
> +{
[...]
> + host->rst_wlan = devm_reset_control_get_exclusive(dev, "wlan");
> + if (IS_ERR(host->rst_wlan))
> + return dev_err_probe(dev, PTR_ERR(host->rst_wlan),
> + "failed to get wlan reset\n");
> +
> + host->rst_wlan_ubus = devm_reset_control_get_exclusive(dev, "wlan-ubus");
> + if (IS_ERR(host->rst_wlan_ubus))
> + return dev_err_probe(dev, PTR_ERR(host->rst_wlan_ubus),
> + "failed to get wlan-ubus reset\n");
[...]
> +}
regards
Philipp