git: a32802d07dc0 - stable/15 - brcm80211: import Broadcom wireless brcmsmac and brcmfmac drivers
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 27 Feb 2026 02:30:08 UTC
The branch stable/15 has been updated by bz:
URL: https://cgit.FreeBSD.org/src/commit/?id=a32802d07dc0ef95854abd892ccba7b016a7490f
commit a32802d07dc0ef95854abd892ccba7b016a7490f
Author: Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2026-02-10 21:22:03 +0000
Commit: Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2026-02-26 23:07:02 +0000
brcm80211: import Broadcom wireless brcmsmac and brcmfmac drivers
This version is based on
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
e5f0a698b34ed76002dc5cff3804a61c80233a7a ( tag: v6.17 ).
We are likely only going to use the brcmfmac driver but given they
come nicely packaged in a directory structure and bwn(9) still uses
GPL-only phy files we could use some of the information from brcmsmac
and fix that (should it ever still be relevant).
(cherry picked from commit b4c3e9b5b09c829b4135aff738bd2893ed052377)
---
sys/contrib/dev/broadcom/brcm80211/Makefile | 13 +
.../dev/broadcom/brcm80211/brcmfmac/Makefile | 62 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/acpi.c | 51 +
.../dev/broadcom/brcm80211/brcmfmac/bca/Makefile | 12 +
.../dev/broadcom/brcm80211/brcmfmac/bca/core.c | 39 +
.../dev/broadcom/brcm80211/brcmfmac/bca/module.c | 28 +
.../dev/broadcom/brcm80211/brcmfmac/bca/vops.h | 11 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/bcdc.c | 490 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/bcdc.h | 20 +
.../dev/broadcom/brcm80211/brcmfmac/bcmsdh.c | 1269 +
.../dev/broadcom/brcm80211/brcmfmac/btcoex.c | 481 +
.../dev/broadcom/brcm80211/brcmfmac/btcoex.h | 18 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/bus.h | 342 +
.../dev/broadcom/brcm80211/brcmfmac/cfg80211.c | 8477 ++++++
.../dev/broadcom/brcm80211/brcmfmac/cfg80211.h | 498 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/chip.c | 1472 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/chip.h | 92 +
.../dev/broadcom/brcm80211/brcmfmac/common.c | 637 +
.../dev/broadcom/brcm80211/brcmfmac/common.h | 95 +
.../dev/broadcom/brcm80211/brcmfmac/commonring.c | 236 +
.../dev/broadcom/brcm80211/brcmfmac/commonring.h | 62 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/core.c | 1576 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/core.h | 228 +
.../dev/broadcom/brcm80211/brcmfmac/cyw/Makefile | 12 +
.../dev/broadcom/brcm80211/brcmfmac/cyw/core.c | 373 +
.../broadcom/brcm80211/brcmfmac/cyw/fwil_types.h | 87 +
.../dev/broadcom/brcm80211/brcmfmac/cyw/module.c | 28 +
.../dev/broadcom/brcm80211/brcmfmac/cyw/vops.h | 11 +
.../dev/broadcom/brcm80211/brcmfmac/debug.c | 56 +
.../dev/broadcom/brcm80211/brcmfmac/debug.h | 143 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/dmi.c | 215 +
.../dev/broadcom/brcm80211/brcmfmac/feature.c | 385 +
.../dev/broadcom/brcm80211/brcmfmac/feature.h | 131 +
.../dev/broadcom/brcm80211/brcmfmac/firmware.c | 859 +
.../dev/broadcom/brcm80211/brcmfmac/firmware.h | 95 +
.../dev/broadcom/brcm80211/brcmfmac/flowring.c | 508 +
.../dev/broadcom/brcm80211/brcmfmac/flowring.h | 74 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/fweh.c | 514 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/fweh.h | 401 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/fwil.c | 432 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/fwil.h | 224 +
.../dev/broadcom/brcm80211/brcmfmac/fwil_types.h | 1239 +
.../dev/broadcom/brcm80211/brcmfmac/fwsignal.c | 2514 ++
.../dev/broadcom/brcm80211/brcmfmac/fwsignal.h | 48 +
.../dev/broadcom/brcm80211/brcmfmac/fwvid.c | 200 +
.../dev/broadcom/brcm80211/brcmfmac/fwvid.h | 88 +
.../dev/broadcom/brcm80211/brcmfmac/msgbuf.c | 1687 ++
.../dev/broadcom/brcm80211/brcmfmac/msgbuf.h | 43 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/of.c | 155 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/of.h | 14 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/p2p.c | 2546 ++
sys/contrib/dev/broadcom/brcm80211/brcmfmac/p2p.h | 179 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/pcie.c | 2785 ++
sys/contrib/dev/broadcom/brcm80211/brcmfmac/pcie.h | 14 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/pno.c | 595 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/pno.h | 72 +
.../dev/broadcom/brcm80211/brcmfmac/proto.c | 71 +
.../dev/broadcom/brcm80211/brcmfmac/proto.h | 155 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/sdio.c | 4650 +++
sys/contrib/dev/broadcom/brcm80211/brcmfmac/sdio.h | 370 +
.../dev/broadcom/brcm80211/brcmfmac/tracepoint.c | 32 +
.../dev/broadcom/brcm80211/brcmfmac/tracepoint.h | 144 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/usb.c | 1604 ++
sys/contrib/dev/broadcom/brcm80211/brcmfmac/usb.h | 42 +
.../dev/broadcom/brcm80211/brcmfmac/vendor.c | 118 +
.../dev/broadcom/brcm80211/brcmfmac/vendor.h | 53 +
.../dev/broadcom/brcm80211/brcmfmac/wcc/Makefile | 12 +
.../dev/broadcom/brcm80211/brcmfmac/wcc/core.c | 40 +
.../dev/broadcom/brcm80211/brcmfmac/wcc/module.c | 28 +
.../dev/broadcom/brcm80211/brcmfmac/wcc/vops.h | 11 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/xtlv.c | 84 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/xtlv.h | 31 +
.../dev/broadcom/brcm80211/brcmsmac/Makefile | 47 +
.../dev/broadcom/brcm80211/brcmsmac/aiutils.c | 707 +
.../dev/broadcom/brcm80211/brcmsmac/aiutils.h | 221 +
.../dev/broadcom/brcm80211/brcmsmac/ampdu.c | 1097 +
.../dev/broadcom/brcm80211/brcmsmac/ampdu.h | 53 +
.../dev/broadcom/brcm80211/brcmsmac/antsel.c | 309 +
.../dev/broadcom/brcm80211/brcmsmac/antsel.h | 27 +
.../brcm80211/brcmsmac/brcms_trace_brcmsmac.h | 102 +
.../brcm80211/brcmsmac/brcms_trace_brcmsmac_msg.h | 92 +
.../brcm80211/brcmsmac/brcms_trace_brcmsmac_tx.h | 110 +
.../brcm80211/brcmsmac/brcms_trace_events.c | 23 +
.../brcm80211/brcmsmac/brcms_trace_events.h | 40 +
.../dev/broadcom/brcm80211/brcmsmac/channel.c | 771 +
.../dev/broadcom/brcm80211/brcmsmac/channel.h | 47 +
sys/contrib/dev/broadcom/brcm80211/brcmsmac/d11.h | 1902 ++
.../dev/broadcom/brcm80211/brcmsmac/debug.c | 246 +
.../dev/broadcom/brcm80211/brcmsmac/debug.h | 75 +
sys/contrib/dev/broadcom/brcm80211/brcmsmac/dma.c | 1556 +
sys/contrib/dev/broadcom/brcm80211/brcmsmac/dma.h | 124 +
sys/contrib/dev/broadcom/brcm80211/brcmsmac/led.h | 38 +
.../dev/broadcom/brcm80211/brcmsmac/mac80211_if.c | 1738 ++
.../dev/broadcom/brcm80211/brcmsmac/mac80211_if.h | 113 +
sys/contrib/dev/broadcom/brcm80211/brcmsmac/main.c | 8065 ++++++
sys/contrib/dev/broadcom/brcm80211/brcmsmac/main.h | 670 +
.../dev/broadcom/brcm80211/brcmsmac/phy/phy_cmn.c | 2497 ++
.../dev/broadcom/brcm80211/brcmsmac/phy/phy_hal.h | 241 +
.../dev/broadcom/brcm80211/brcmsmac/phy/phy_int.h | 1113 +
.../dev/broadcom/brcm80211/brcmsmac/phy/phy_lcn.c | 5151 ++++
.../dev/broadcom/brcm80211/brcmsmac/phy/phy_lcn.h | 110 +
.../dev/broadcom/brcm80211/brcmsmac/phy/phy_n.c | 28572 +++++++++++++++++++
.../broadcom/brcm80211/brcmsmac/phy/phy_qmath.c | 298 +
.../broadcom/brcm80211/brcmsmac/phy/phy_qmath.h | 31 +
.../broadcom/brcm80211/brcmsmac/phy/phy_radio.h | 1522 +
.../dev/broadcom/brcm80211/brcmsmac/phy/phyreg_n.h | 156 +
.../broadcom/brcm80211/brcmsmac/phy/phytbl_lcn.c | 3170 ++
.../broadcom/brcm80211/brcmsmac/phy/phytbl_lcn.h | 44 +
.../dev/broadcom/brcm80211/brcmsmac/phy/phytbl_n.c | 10099 +++++++
.../dev/broadcom/brcm80211/brcmsmac/phy/phytbl_n.h | 39 +
.../dev/broadcom/brcm80211/brcmsmac/phy_shim.c | 215 +
.../dev/broadcom/brcm80211/brcmsmac/phy_shim.h | 172 +
sys/contrib/dev/broadcom/brcm80211/brcmsmac/pmu.c | 165 +
sys/contrib/dev/broadcom/brcm80211/brcmsmac/pmu.h | 26 +
sys/contrib/dev/broadcom/brcm80211/brcmsmac/pub.h | 341 +
sys/contrib/dev/broadcom/brcm80211/brcmsmac/rate.c | 514 +
sys/contrib/dev/broadcom/brcm80211/brcmsmac/rate.h | 245 +
sys/contrib/dev/broadcom/brcm80211/brcmsmac/scb.h | 67 +
sys/contrib/dev/broadcom/brcm80211/brcmsmac/stf.c | 437 +
sys/contrib/dev/broadcom/brcm80211/brcmsmac/stf.h | 36 +
.../dev/broadcom/brcm80211/brcmsmac/types.h | 294 +
.../dev/broadcom/brcm80211/brcmsmac/ucode_loader.c | 109 +
.../dev/broadcom/brcm80211/brcmsmac/ucode_loader.h | 56 +
.../dev/broadcom/brcm80211/brcmutil/Makefile | 10 +
sys/contrib/dev/broadcom/brcm80211/brcmutil/d11.c | 247 +
.../dev/broadcom/brcm80211/brcmutil/utils.c | 327 +
.../dev/broadcom/brcm80211/include/brcm_hw_ids.h | 116 +
.../dev/broadcom/brcm80211/include/brcmu_d11.h | 156 +
.../dev/broadcom/brcm80211/include/brcmu_utils.h | 216 +
.../dev/broadcom/brcm80211/include/brcmu_wifi.h | 247 +
.../dev/broadcom/brcm80211/include/chipcommon.h | 311 +
sys/contrib/dev/broadcom/brcm80211/include/defs.h | 94 +
sys/contrib/dev/broadcom/brcm80211/include/soc.h | 25 +
133 files changed, 116023 insertions(+)
diff --git a/sys/contrib/dev/broadcom/brcm80211/Makefile b/sys/contrib/dev/broadcom/brcm80211/Makefile
new file mode 100644
index 000000000000..88115d072624
--- /dev/null
+++ b/sys/contrib/dev/broadcom/brcm80211/Makefile
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: ISC
+#
+# Makefile fragment for Broadcom 802.11 Networking Device Driver
+#
+# Copyright (c) 2010 Broadcom Corporation
+#
+
+# common flags
+subdir-ccflags-$(CONFIG_BRCMDBG) += -DDEBUG
+
+obj-$(CONFIG_BRCMUTIL) += brcmutil/
+obj-$(CONFIG_BRCMFMAC) += brcmfmac/
+obj-$(CONFIG_BRCMSMAC) += brcmsmac/
diff --git a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/Makefile b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/Makefile
new file mode 100644
index 000000000000..e5ca0f511822
--- /dev/null
+++ b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/Makefile
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: ISC
+#
+# Makefile fragment for Broadcom 802.11 Networking Device Driver
+#
+# Copyright (c) 2010 Broadcom Corporation
+#
+
+ccflags-y += \
+ -I $(src) \
+ -I $(src)/../include
+
+obj-$(CONFIG_BRCMFMAC) += brcmfmac.o
+brcmfmac-objs += \
+ cfg80211.o \
+ chip.o \
+ fwil.o \
+ fweh.o \
+ p2p.o \
+ proto.o \
+ common.o \
+ core.o \
+ firmware.o \
+ fwvid.o \
+ feature.o \
+ btcoex.o \
+ vendor.o \
+ pno.o \
+ xtlv.o
+brcmfmac-$(CONFIG_BRCMFMAC_PROTO_BCDC) += \
+ bcdc.o \
+ fwsignal.o
+brcmfmac-$(CONFIG_BRCMFMAC_PROTO_MSGBUF) += \
+ commonring.o \
+ flowring.o \
+ msgbuf.o
+brcmfmac-$(CONFIG_BRCMFMAC_SDIO) += \
+ sdio.o \
+ bcmsdh.o
+brcmfmac-$(CONFIG_BRCMFMAC_USB) += \
+ usb.o
+brcmfmac-$(CONFIG_BRCMFMAC_PCIE) += \
+ pcie.o
+brcmfmac-$(CONFIG_BRCMDBG) += \
+ debug.o
+brcmfmac-$(CONFIG_BRCM_TRACING) += \
+ tracepoint.o
+brcmfmac-$(CONFIG_OF) += \
+ of.o
+brcmfmac-$(CONFIG_DMI) += \
+ dmi.o
+brcmfmac-$(CONFIG_ACPI) += \
+ acpi.o
+
+ifeq ($(CONFIG_BRCMFMAC),m)
+obj-m += wcc/
+obj-m += cyw/
+obj-m += bca/
+else
+brcmfmac-$(CONFIG_BRCMFMAC) += wcc/core.o
+brcmfmac-$(CONFIG_BRCMFMAC) += cyw/core.o
+brcmfmac-$(CONFIG_BRCMFMAC) += bca/core.o
+endif
diff --git a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/acpi.c b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/acpi.c
new file mode 100644
index 000000000000..c4a54861bfb4
--- /dev/null
+++ b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/acpi.c
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Copyright The Asahi Linux Contributors
+ */
+
+#include <linux/acpi.h>
+#include "debug.h"
+#include "core.h"
+#include "common.h"
+
+void brcmf_acpi_probe(struct device *dev, enum brcmf_bus_type bus_type,
+ struct brcmf_mp_device *settings)
+{
+ acpi_status status;
+ const union acpi_object *o;
+ struct acpi_buffer buf = {ACPI_ALLOCATE_BUFFER, NULL};
+ struct acpi_device *adev = ACPI_COMPANION(dev);
+
+ if (!adev)
+ return;
+
+ if (!ACPI_FAILURE(acpi_dev_get_property(adev, "module-instance",
+ ACPI_TYPE_STRING, &o))) {
+ brcmf_dbg(INFO, "ACPI module-instance=%s\n", o->string.pointer);
+ settings->board_type = devm_kasprintf(dev, GFP_KERNEL,
+ "apple,%s",
+ o->string.pointer);
+ } else {
+ brcmf_dbg(INFO, "No ACPI module-instance\n");
+ return;
+ }
+
+ status = acpi_evaluate_object(adev->handle, "RWCV", NULL, &buf);
+ o = buf.pointer;
+ if (!ACPI_FAILURE(status) && o && o->type == ACPI_TYPE_BUFFER &&
+ o->buffer.length >= 2) {
+ char *antenna_sku = devm_kzalloc(dev, 3, GFP_KERNEL);
+
+ if (antenna_sku) {
+ memcpy(antenna_sku, o->buffer.pointer, 2);
+ brcmf_dbg(INFO, "ACPI RWCV data=%*phN antenna-sku=%s\n",
+ (int)o->buffer.length, o->buffer.pointer,
+ antenna_sku);
+ settings->antenna_sku = antenna_sku;
+ }
+
+ kfree(buf.pointer);
+ } else {
+ brcmf_dbg(INFO, "No ACPI antenna-sku\n");
+ }
+}
diff --git a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bca/Makefile b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bca/Makefile
new file mode 100644
index 000000000000..5e37c638f966
--- /dev/null
+++ b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bca/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: ISC
+#
+# Copyright (c) 2022 Broadcom Corporation
+
+ccflags-y += \
+ -I $(src) \
+ -I $(src)/.. \
+ -I $(src)/../../include
+
+obj-m += brcmfmac-bca.o
+brcmfmac-bca-objs += \
+ core.o module.o
diff --git a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bca/core.c b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bca/core.c
new file mode 100644
index 000000000000..f471c962104a
--- /dev/null
+++ b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bca/core.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Copyright (c) 2022 Broadcom Corporation
+ */
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <core.h>
+#include <bus.h>
+#include <fwvid.h>
+#include <feature.h>
+
+#include "vops.h"
+
+#define BRCMF_BCA_E_LAST 212
+
+static void brcmf_bca_feat_attach(struct brcmf_if *ifp)
+{
+ /* SAE support not confirmed so disabling for now */
+ ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_SAE);
+}
+
+static int brcmf_bca_alloc_fweh_info(struct brcmf_pub *drvr)
+{
+ struct brcmf_fweh_info *fweh;
+
+ fweh = kzalloc(struct_size(fweh, evt_handler, BRCMF_BCA_E_LAST),
+ GFP_KERNEL);
+ if (!fweh)
+ return -ENOMEM;
+
+ fweh->num_event_codes = BRCMF_BCA_E_LAST;
+ drvr->fweh = fweh;
+ return 0;
+}
+
+const struct brcmf_fwvid_ops brcmf_bca_ops = {
+ .feat_attach = brcmf_bca_feat_attach,
+ .alloc_fweh_info = brcmf_bca_alloc_fweh_info,
+};
diff --git a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bca/module.c b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bca/module.c
new file mode 100644
index 000000000000..1e1c79b18c5b
--- /dev/null
+++ b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bca/module.c
@@ -0,0 +1,28 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Copyright (c) 2022 Broadcom Corporation
+ */
+#include <linux/module.h>
+#include <bus.h>
+#include <core.h>
+#include <fwvid.h>
+
+#include "vops.h"
+
+static int __init brcmf_bca_init(void)
+{
+ return brcmf_fwvid_register_vendor(BRCMF_FWVENDOR_BCA, THIS_MODULE,
+ &brcmf_bca_ops);
+}
+
+static void __exit brcmf_bca_exit(void)
+{
+ brcmf_fwvid_unregister_vendor(BRCMF_FWVENDOR_BCA, THIS_MODULE);
+}
+
+MODULE_DESCRIPTION("Broadcom FullMAC WLAN driver plugin for Broadcom AP chipsets");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_IMPORT_NS("BRCMFMAC");
+
+module_init(brcmf_bca_init);
+module_exit(brcmf_bca_exit);
diff --git a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bca/vops.h b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bca/vops.h
new file mode 100644
index 000000000000..7897e6b6eefb
--- /dev/null
+++ b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bca/vops.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: ISC */
+/*
+ * Copyright (c) 2022 Broadcom Corporation
+ */
+#ifndef _BRCMFMAC_BCA_VOPS_H
+#define _BRCMFMAC_BCA_VOPS_H
+
+extern const struct brcmf_fwvid_ops brcmf_bca_ops;
+#define BCA_VOPS (&brcmf_bca_ops)
+
+#endif /* _BRCMFMAC_BCA_VOPS_H */
diff --git a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bcdc.c b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bcdc.c
new file mode 100644
index 000000000000..9ec0c60b6da1
--- /dev/null
+++ b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bcdc.c
@@ -0,0 +1,490 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ */
+
+/*******************************************************************************
+ * Communicates with the dongle by using dcmd codes.
+ * For certain dcmd codes, the dongle interprets string data from the host.
+ ******************************************************************************/
+
+#include <linux/types.h>
+#include <linux/netdevice.h>
+
+#include <brcmu_utils.h>
+#include <brcmu_wifi.h>
+
+#include "core.h"
+#include "bus.h"
+#include "fwsignal.h"
+#include "debug.h"
+#include "tracepoint.h"
+#include "proto.h"
+#include "bcdc.h"
+
+struct brcmf_proto_bcdc_dcmd {
+ __le32 cmd; /* dongle command value */
+ __le32 len; /* lower 16: output buflen;
+ * upper 16: input buflen (excludes header) */
+ __le32 flags; /* flag defns given below */
+ __le32 status; /* status code returned from the device */
+};
+
+/* BCDC flag definitions */
+#define BCDC_DCMD_ERROR 0x01 /* 1=cmd failed */
+#define BCDC_DCMD_SET 0x02 /* 0=get, 1=set cmd */
+#define BCDC_DCMD_IF_MASK 0xF000 /* I/F index */
+#define BCDC_DCMD_IF_SHIFT 12
+#define BCDC_DCMD_ID_MASK 0xFFFF0000 /* id an cmd pairing */
+#define BCDC_DCMD_ID_SHIFT 16 /* ID Mask shift bits */
+#define BCDC_DCMD_ID(flags) \
+ (((flags) & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT)
+
+/*
+ * BCDC header - Broadcom specific extension of CDC.
+ * Used on data packets to convey priority across USB.
+ */
+#define BCDC_HEADER_LEN 4
+#define BCDC_PROTO_VER 2 /* Protocol version */
+#define BCDC_FLAG_VER_MASK 0xf0 /* Protocol version mask */
+#define BCDC_FLAG_VER_SHIFT 4 /* Protocol version shift */
+#define BCDC_FLAG_SUM_GOOD 0x04 /* Good RX checksums */
+#define BCDC_FLAG_SUM_NEEDED 0x08 /* Dongle needs to do TX checksums */
+#define BCDC_PRIORITY_MASK 0x7
+#define BCDC_FLAG2_IF_MASK 0x0f /* packet rx interface in APSTA */
+#define BCDC_FLAG2_IF_SHIFT 0
+
+#define BCDC_GET_IF_IDX(hdr) \
+ ((int)((((hdr)->flags2) & BCDC_FLAG2_IF_MASK) >> BCDC_FLAG2_IF_SHIFT))
+#define BCDC_SET_IF_IDX(hdr, idx) \
+ ((hdr)->flags2 = (((hdr)->flags2 & ~BCDC_FLAG2_IF_MASK) | \
+ ((idx) << BCDC_FLAG2_IF_SHIFT)))
+
+/**
+ * struct brcmf_proto_bcdc_header - BCDC header format
+ *
+ * @flags: flags contain protocol and checksum info.
+ * @priority: 802.1d priority and USB flow control info (bit 4:7).
+ * @flags2: additional flags containing dongle interface index.
+ * @data_offset: start of packet data. header is following by firmware signals.
+ */
+struct brcmf_proto_bcdc_header {
+ u8 flags;
+ u8 priority;
+ u8 flags2;
+ u8 data_offset;
+};
+
+/*
+ * maximum length of firmware signal data between
+ * the BCDC header and packet data in the tx path.
+ */
+#define BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES 12
+
+#define RETRIES 2 /* # of retries to retrieve matching dcmd response */
+#define BUS_HEADER_LEN (16+64) /* Must be atleast SDPCM_RESERVE
+ * (amount of header tha might be added)
+ * plus any space that might be needed
+ * for bus alignment padding.
+ */
+#define ROUND_UP_MARGIN 2048
+
+struct brcmf_bcdc {
+ u16 reqid;
+ u8 bus_header[BUS_HEADER_LEN];
+ struct brcmf_proto_bcdc_dcmd msg;
+ unsigned char buf[BRCMF_DCMD_MAXLEN];
+ struct brcmf_fws_info *fws;
+};
+
+
+struct brcmf_fws_info *drvr_to_fws(struct brcmf_pub *drvr)
+{
+ struct brcmf_bcdc *bcdc = drvr->proto->pd;
+
+ return bcdc->fws;
+}
+
+static int
+brcmf_proto_bcdc_msg(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf,
+ uint len, bool set)
+{
+ struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
+ struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
+ u32 flags;
+
+ brcmf_dbg(BCDC, "Enter\n");
+
+ memset(msg, 0, sizeof(struct brcmf_proto_bcdc_dcmd));
+
+ msg->cmd = cpu_to_le32(cmd);
+ msg->len = cpu_to_le32(len);
+ flags = (++bcdc->reqid << BCDC_DCMD_ID_SHIFT);
+ if (set)
+ flags |= BCDC_DCMD_SET;
+ flags = (flags & ~BCDC_DCMD_IF_MASK) |
+ (ifidx << BCDC_DCMD_IF_SHIFT);
+ msg->flags = cpu_to_le32(flags);
+
+ if (buf)
+ memcpy(bcdc->buf, buf, len);
+
+ len += sizeof(*msg);
+ if (len > BRCMF_TX_IOCTL_MAX_MSG_SIZE)
+ len = BRCMF_TX_IOCTL_MAX_MSG_SIZE;
+
+ /* Send request */
+ return brcmf_bus_txctl(drvr->bus_if, (unsigned char *)&bcdc->msg, len);
+}
+
+static int brcmf_proto_bcdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len)
+{
+ int ret;
+ struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
+
+ brcmf_dbg(BCDC, "Enter\n");
+ len += sizeof(struct brcmf_proto_bcdc_dcmd);
+ do {
+ ret = brcmf_bus_rxctl(drvr->bus_if, (unsigned char *)&bcdc->msg,
+ len);
+ if (ret < 0)
+ break;
+ } while (BCDC_DCMD_ID(le32_to_cpu(bcdc->msg.flags)) != id);
+
+ return ret;
+}
+
+static int
+brcmf_proto_bcdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
+ void *buf, uint len, int *fwerr)
+{
+ struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
+ struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
+ void *info;
+ int ret = 0, retries = 0;
+ u32 id, flags;
+
+ brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
+
+ *fwerr = 0;
+ ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, false);
+ if (ret < 0) {
+ bphy_err(drvr, "brcmf_proto_bcdc_msg failed w/status %d\n",
+ ret);
+ goto done;
+ }
+
+retry:
+ /* wait for interrupt and get first fragment */
+ ret = brcmf_proto_bcdc_cmplt(drvr, bcdc->reqid, len);
+ if (ret < 0)
+ goto done;
+
+ flags = le32_to_cpu(msg->flags);
+ id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT;
+
+ if ((id < bcdc->reqid) && (++retries < RETRIES))
+ goto retry;
+ if (id != bcdc->reqid) {
+ bphy_err(drvr, "%s: unexpected request id %d (expected %d)\n",
+ brcmf_ifname(brcmf_get_ifp(drvr, ifidx)), id,
+ bcdc->reqid);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ /* Check info buffer */
+ info = (void *)&bcdc->buf[0];
+
+ /* Copy info buffer */
+ if (buf) {
+ if (ret < (int)len)
+ len = ret;
+ memcpy(buf, info, len);
+ }
+
+ ret = 0;
+
+ /* Check the ERROR flag */
+ if (flags & BCDC_DCMD_ERROR)
+ *fwerr = le32_to_cpu(msg->status);
+done:
+ return ret;
+}
+
+static int
+brcmf_proto_bcdc_set_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd,
+ void *buf, uint len, int *fwerr)
+{
+ struct brcmf_bcdc *bcdc = (struct brcmf_bcdc *)drvr->proto->pd;
+ struct brcmf_proto_bcdc_dcmd *msg = &bcdc->msg;
+ int ret;
+ u32 flags, id;
+
+ brcmf_dbg(BCDC, "Enter, cmd %d len %d\n", cmd, len);
+
+ *fwerr = 0;
+ ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, true);
+ if (ret < 0)
+ goto done;
+
+ ret = brcmf_proto_bcdc_cmplt(drvr, bcdc->reqid, len);
+ if (ret < 0)
+ goto done;
+
+ flags = le32_to_cpu(msg->flags);
+ id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT;
+
+ if (id != bcdc->reqid) {
+ bphy_err(drvr, "%s: unexpected request id %d (expected %d)\n",
+ brcmf_ifname(brcmf_get_ifp(drvr, ifidx)), id,
+ bcdc->reqid);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ ret = 0;
+
+ /* Check the ERROR flag */
+ if (flags & BCDC_DCMD_ERROR)
+ *fwerr = le32_to_cpu(msg->status);
+
+done:
+ return ret;
+}
+
+static void
+brcmf_proto_bcdc_hdrpush(struct brcmf_pub *drvr, int ifidx, u8 offset,
+ struct sk_buff *pktbuf)
+{
+ struct brcmf_proto_bcdc_header *h;
+
+ brcmf_dbg(BCDC, "Enter\n");
+
+ /* Push BDC header used to convey priority for buses that don't */
+ skb_push(pktbuf, BCDC_HEADER_LEN);
+
+ h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
+
+ h->flags = (BCDC_PROTO_VER << BCDC_FLAG_VER_SHIFT);
+ if (pktbuf->ip_summed == CHECKSUM_PARTIAL)
+ h->flags |= BCDC_FLAG_SUM_NEEDED;
+
+ h->priority = (pktbuf->priority & BCDC_PRIORITY_MASK);
+ h->flags2 = 0;
+ h->data_offset = offset;
+ BCDC_SET_IF_IDX(h, ifidx);
+ trace_brcmf_bcdchdr(pktbuf->data);
+}
+
+static int
+brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws,
+ struct sk_buff *pktbuf, struct brcmf_if **ifp)
+{
+ struct brcmf_proto_bcdc_header *h;
+ struct brcmf_if *tmp_if;
+
+ brcmf_dbg(BCDC, "Enter\n");
+
+ /* Pop BCDC header used to convey priority for buses that don't */
+ if (pktbuf->len <= BCDC_HEADER_LEN) {
+ brcmf_dbg(INFO, "rx data too short (%d <= %d)\n",
+ pktbuf->len, BCDC_HEADER_LEN);
+ return -EBADE;
+ }
+
+ trace_brcmf_bcdchdr(pktbuf->data);
+ h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
+
+ tmp_if = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h));
+ if (!tmp_if) {
+ brcmf_dbg(INFO, "no matching ifp found\n");
+ return -EBADE;
+ }
+ if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
+ BCDC_PROTO_VER) {
+ bphy_err(drvr, "%s: non-BCDC packet received, flags 0x%x\n",
+ brcmf_ifname(tmp_if), h->flags);
+ return -EBADE;
+ }
+
+ if (h->flags & BCDC_FLAG_SUM_GOOD) {
+ brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
+ brcmf_ifname(tmp_if), h->flags);
+ pktbuf->ip_summed = CHECKSUM_UNNECESSARY;
+ }
+
+ pktbuf->priority = h->priority & BCDC_PRIORITY_MASK;
+
+ skb_pull(pktbuf, BCDC_HEADER_LEN);
+ if (do_fws)
+ brcmf_fws_hdrpull(tmp_if, h->data_offset << 2, pktbuf);
+ else
+ skb_pull(pktbuf, h->data_offset << 2);
+
+ if (pktbuf->len == 0)
+ return -ENODATA;
+
+ if (ifp != NULL)
+ *ifp = tmp_if;
+ return 0;
+}
+
+static int brcmf_proto_bcdc_tx_queue_data(struct brcmf_pub *drvr, int ifidx,
+ struct sk_buff *skb)
+{
+ struct brcmf_if *ifp = brcmf_get_ifp(drvr, ifidx);
+ struct brcmf_bcdc *bcdc = drvr->proto->pd;
+
+ if (!brcmf_fws_queue_skbs(bcdc->fws))
+ return brcmf_proto_txdata(drvr, ifidx, 0, skb);
+
+ return brcmf_fws_process_skb(ifp, skb);
+}
+
+static int
+brcmf_proto_bcdc_txdata(struct brcmf_pub *drvr, int ifidx, u8 offset,
+ struct sk_buff *pktbuf)
+{
+ brcmf_proto_bcdc_hdrpush(drvr, ifidx, offset, pktbuf);
+ return brcmf_bus_txdata(drvr->bus_if, pktbuf);
+}
+
+void brcmf_proto_bcdc_txflowblock(struct device *dev, bool state)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_pub *drvr = bus_if->drvr;
+
+ brcmf_dbg(TRACE, "Enter\n");
+
+ brcmf_fws_bus_blocked(drvr, state);
+}
+
+void
+brcmf_proto_bcdc_txcomplete(struct device *dev, struct sk_buff *txp,
+ bool success)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
+ struct brcmf_bcdc *bcdc = bus_if->drvr->proto->pd;
+ struct brcmf_if *ifp;
+
+ /* await txstatus signal for firmware if active */
+ if (brcmf_fws_fc_active(bcdc->fws)) {
+ brcmf_fws_bustxcomplete(bcdc->fws, txp, success);
+ } else {
+ if (brcmf_proto_bcdc_hdrpull(bus_if->drvr, false, txp, &ifp))
+ brcmu_pkt_buf_free_skb(txp);
+ else
+ brcmf_txfinalize(ifp, txp, success);
+ }
+}
+
+static void
+brcmf_proto_bcdc_configure_addr_mode(struct brcmf_pub *drvr, int ifidx,
+ enum proto_addr_mode addr_mode)
+{
+}
+
+static void
+brcmf_proto_bcdc_delete_peer(struct brcmf_pub *drvr, int ifidx,
+ u8 peer[ETH_ALEN])
+{
+}
+
+static void
+brcmf_proto_bcdc_add_tdls_peer(struct brcmf_pub *drvr, int ifidx,
+ u8 peer[ETH_ALEN])
+{
+}
+
+static void brcmf_proto_bcdc_rxreorder(struct brcmf_if *ifp,
+ struct sk_buff *skb)
+{
+ brcmf_fws_rxreorder(ifp, skb);
+}
+
+static void
+brcmf_proto_bcdc_add_if(struct brcmf_if *ifp)
+{
+ brcmf_fws_add_interface(ifp);
+}
+
+static void
+brcmf_proto_bcdc_del_if(struct brcmf_if *ifp)
+{
+ brcmf_fws_del_interface(ifp);
+}
+
+static void
+brcmf_proto_bcdc_reset_if(struct brcmf_if *ifp)
+{
+ brcmf_fws_reset_interface(ifp);
+}
+
+static int
+brcmf_proto_bcdc_init_done(struct brcmf_pub *drvr)
+{
+ struct brcmf_bcdc *bcdc = drvr->proto->pd;
+ struct brcmf_fws_info *fws;
+
+ fws = brcmf_fws_attach(drvr);
+ if (IS_ERR(fws))
+ return PTR_ERR(fws);
+
+ bcdc->fws = fws;
+ return 0;
+}
+
+static void brcmf_proto_bcdc_debugfs_create(struct brcmf_pub *drvr)
+{
+ brcmf_fws_debugfs_create(drvr);
+}
+
+int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr)
+{
+ struct brcmf_bcdc *bcdc;
+
+ bcdc = kzalloc(sizeof(*bcdc), GFP_ATOMIC);
+ if (!bcdc)
+ goto fail;
+
+ /* ensure that the msg buf directly follows the cdc msg struct */
+ if ((unsigned long)(&bcdc->msg + 1) != (unsigned long)bcdc->buf) {
+ bphy_err(drvr, "struct brcmf_proto_bcdc is not correctly defined\n");
+ goto fail;
+ }
+
+ drvr->proto->hdrpull = brcmf_proto_bcdc_hdrpull;
+ drvr->proto->query_dcmd = brcmf_proto_bcdc_query_dcmd;
+ drvr->proto->set_dcmd = brcmf_proto_bcdc_set_dcmd;
+ drvr->proto->tx_queue_data = brcmf_proto_bcdc_tx_queue_data;
+ drvr->proto->txdata = brcmf_proto_bcdc_txdata;
+ drvr->proto->configure_addr_mode = brcmf_proto_bcdc_configure_addr_mode;
+ drvr->proto->delete_peer = brcmf_proto_bcdc_delete_peer;
+ drvr->proto->add_tdls_peer = brcmf_proto_bcdc_add_tdls_peer;
+ drvr->proto->rxreorder = brcmf_proto_bcdc_rxreorder;
+ drvr->proto->add_if = brcmf_proto_bcdc_add_if;
+ drvr->proto->del_if = brcmf_proto_bcdc_del_if;
+ drvr->proto->reset_if = brcmf_proto_bcdc_reset_if;
+ drvr->proto->init_done = brcmf_proto_bcdc_init_done;
+ drvr->proto->debugfs_create = brcmf_proto_bcdc_debugfs_create;
+ drvr->proto->pd = bcdc;
+
+ drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES;
+ drvr->bus_if->maxctl = BRCMF_DCMD_MAXLEN +
+ sizeof(struct brcmf_proto_bcdc_dcmd) + ROUND_UP_MARGIN;
+ return 0;
+
+fail:
+ kfree(bcdc);
+ return -ENOMEM;
+}
+
+void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr)
+{
+ struct brcmf_bcdc *bcdc = drvr->proto->pd;
+
+ drvr->proto->pd = NULL;
+ brcmf_fws_detach(bcdc->fws);
+ kfree(bcdc);
+}
diff --git a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bcdc.h b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bcdc.h
new file mode 100644
index 000000000000..b051d2860cd1
--- /dev/null
+++ b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bcdc.h
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Copyright (c) 2013 Broadcom Corporation
+ */
+#ifndef BRCMFMAC_BCDC_H
+#define BRCMFMAC_BCDC_H
+
+#ifdef CONFIG_BRCMFMAC_PROTO_BCDC
+int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr);
+void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr);
+void brcmf_proto_bcdc_txflowblock(struct device *dev, bool state);
+void brcmf_proto_bcdc_txcomplete(struct device *dev, struct sk_buff *txp,
+ bool success);
+struct brcmf_fws_info *drvr_to_fws(struct brcmf_pub *drvr);
+#else
+static inline int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { return 0; }
+static inline void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) {}
+#endif
+
+#endif /* BRCMFMAC_BCDC_H */
diff --git a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bcmsdh.c b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bcmsdh.c
new file mode 100644
index 000000000000..8ab7d1e34a6e
--- /dev/null
+++ b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -0,0 +1,1269 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Copyright (c) 2010 Broadcom Corporation
+ */
+/* ****************** SDIO CARD Interface Functions **************************/
+
+#include <linux/types.h>
+#include <linux/netdevice.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/sched.h>
+#include <linux/completion.h>
+#include <linux/interrupt.h>
+#include <linux/scatterlist.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/core.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+#include <linux/pm_runtime.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/acpi.h>
+#include <net/cfg80211.h>
+
+#include <defs.h>
+#include <brcm_hw_ids.h>
+#include <brcmu_utils.h>
+#include <brcmu_wifi.h>
+#include <chipcommon.h>
+#include <soc.h>
+#include "chip.h"
+#include "bus.h"
+#include "debug.h"
+#include "sdio.h"
+#include "core.h"
+#include "common.h"
+
+#define SDIOH_API_ACCESS_RETRY_LIMIT 2
+
+#define DMA_ALIGN_MASK 0x03
+
*** 115992 LINES SKIPPED ***