Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 27 Feb 2026 02:30:08 +0000
From:      Bjoern A. Zeeb <bz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: a32802d07dc0 - stable/15 - brcm80211: import Broadcom wireless brcmsmac and brcmfmac drivers
Message-ID:  <69a101b0.21afa.61c82ca1@gitrepo.freebsd.org>

index | next in thread | raw e-mail

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 ***


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69a101b0.21afa.61c82ca1>