git: 902136e0fe11 - main - brcm80211: add LinuxKPI files and module Makefiles
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 10 Feb 2026 21:54:30 UTC
The branch main has been updated by bz:
URL: https://cgit.FreeBSD.org/src/commit/?id=902136e0fe112383ec64d2ef43a446063b5e6417
commit 902136e0fe112383ec64d2ef43a446063b5e6417
Author: Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2026-02-10 21:33:09 +0000
Commit: Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2026-02-10 21:36:29 +0000
brcm80211: add LinuxKPI files and module Makefiles
sys/compat/linuxkpi/common/include/linux/platform_data/brcmfmac.h
is based on
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
e5f0a698b34ed76002dc5cff3804a61c80233a7a ( tag: v6.17 ).
Currently only PCIe is made to compile.
It does load firmware (if needed, e.g., on arm64 with an alignment
issue fixed), and starts to come up.
To make it work there is a cfg80211 layer and netdevice integration
to do, so do not hold your breath just yet.
---
.../linuxkpi/common/include/linux/bcm47xx_nvram.h | 21 +++
.../linuxkpi/common/include/linux/bcma/bcma.h | 29 ++++
.../linuxkpi/common/include/linux/bcma/bcma_regs.h | 17 ++
.../common/include/linux/platform_data/brcmfmac.h | 185 ++++++++++++++++++++
.../linuxkpi/common/include/linux/ssb/ssb_regs.h | 25 +++
.../dev/broadcom/brcm80211/brcmfmac/cfg80211.c | 190 +++++++++++++++++++++
.../dev/broadcom/brcm80211/brcmfmac/common.c | 35 ++++
.../dev/broadcom/brcm80211/brcmfmac/commonring.c | 15 ++
.../dev/broadcom/brcm80211/brcmfmac/debug.c | 8 +
.../dev/broadcom/brcm80211/brcmfmac/debug.h | 24 +++
.../dev/broadcom/brcm80211/brcmfmac/firmware.c | 24 +++
.../dev/broadcom/brcm80211/brcmfmac/flowring.c | 24 +++
.../dev/broadcom/brcm80211/brcmfmac/flowring.h | 8 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/fwil.c | 8 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/fwil.h | 4 +
.../dev/broadcom/brcm80211/brcmfmac/fwvid.c | 18 ++
.../dev/broadcom/brcm80211/brcmfmac/msgbuf.c | 34 ++++
sys/contrib/dev/broadcom/brcm80211/brcmfmac/p2p.c | 23 +++
sys/contrib/dev/broadcom/brcm80211/brcmfmac/pcie.c | 117 +++++++++++++
sys/contrib/dev/broadcom/brcm80211/brcmfmac/pno.c | 21 +++
.../dev/broadcom/brcm80211/brcmfmac/proto.h | 16 ++
.../dev/broadcom/brcm80211/brcmfmac/tracepoint.h | 18 ++
.../dev/broadcom/brcm80211/brcmfmac/vendor.c | 9 +
sys/contrib/dev/broadcom/brcm80211/brcmfmac/xtlv.c | 4 +
.../dev/broadcom/brcm80211/brcmutil/utils.c | 9 +
sys/modules/brcm80211/Makefile | 4 +
sys/modules/brcm80211/brcmfmac/Makefile | 89 ++++++++++
sys/modules/brcm80211/brcmutil/Makefile | 28 +++
28 files changed, 1007 insertions(+)
diff --git a/sys/compat/linuxkpi/common/include/linux/bcm47xx_nvram.h b/sys/compat/linuxkpi/common/include/linux/bcm47xx_nvram.h
new file mode 100644
index 000000000000..744101a2f8b1
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/bcm47xx_nvram.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2025 Bjoern A. Zeeb
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_LINUX_BCM47XX_NVRAM_H
+#define _LINUXKPI_LINUX_BCM47XX_NVRAM_H
+
+static inline char *
+bcm47xx_nvram_get_contents(size_t *x __unused)
+{
+ return (NULL);
+};
+
+static inline void
+bcm47xx_nvram_release_contents(const char *x __unused)
+{
+};
+
+#endif /* _LINUXKPI_LINUX_BCM47XX_NVRAM_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/bcma/bcma.h b/sys/compat/linuxkpi/common/include/linux/bcma/bcma.h
new file mode 100644
index 000000000000..3840c3a420e5
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/bcma/bcma.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2025 Bjoern A. Zeeb
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_LINUX_BCMA_BCMA_H
+#define _LINUXKPI_LINUX_BCMA_BCMA_H
+
+#define BCMA_CORE_80211 0x812
+#define BCMA_CORE_ARM_CA7 0x847
+#define BCMA_CORE_ARM_CM3 0x82A
+#define BCMA_CORE_ARM_CR4 0x83E
+#define BCMA_CORE_CHIPCOMMON 0x800
+#define BCMA_CORE_GCI 0x840
+#define BCMA_CORE_INTERNAL_MEM 0x80E
+#define BCMA_CORE_PCIE2 0x83C
+#define BCMA_CORE_PMU 0x827
+#define BCMA_CORE_SDIO_DEV 0x829
+#define BCMA_CORE_SYS_MEM 0x849
+
+/* XXX not sure where these belong. */
+#define BCMA_CC_CAP_EXT_AOB_PRESENT 0x00000040
+#define BCMA_CC_PMU_CTL_RES_SHIFT 13
+#define BCMA_CC_PMU_CTL_RES_RELOAD 0x2
+#define BCMA_CC_SROM_CONTROL_OTPSEL 0x00000010
+#define BCMA_CC_SROM_CONTROL_OTP_PRESENT 0x00000020
+
+#endif /* _LINUXKPI_LINUX_BCMA_BCMA_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/bcma/bcma_regs.h b/sys/compat/linuxkpi/common/include/linux/bcma/bcma_regs.h
new file mode 100644
index 000000000000..0a4cdddf7a73
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/bcma/bcma_regs.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2025 Bjoern A. Zeeb
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_LINUX_BCMA_BCMA_REGS_H
+#define _LINUXKPI_LINUX_BCMA_BCMA_REGS_H
+
+#define BCMA_IOCTL 0x0408
+#define BCMA_IOCTL_CLK 0x0001
+#define BCMA_IOCTL_FGC 0x0002
+
+#define BCMA_RESET_CTL 0x0800
+#define BCMA_RESET_CTL_RESET 0x0001
+
+#endif /* _LINUXKPI_LINUX_BCMA_BCMA_REGS_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/platform_data/brcmfmac.h b/sys/compat/linuxkpi/common/include/linux/platform_data/brcmfmac.h
new file mode 100644
index 000000000000..ec99b7b73d1d
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/platform_data/brcmfmac.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2016 Broadcom Corporation
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _LINUX_BRCMFMAC_PLATFORM_H
+#define _LINUX_BRCMFMAC_PLATFORM_H
+
+
+#define BRCMFMAC_PDATA_NAME "brcmfmac"
+
+#define BRCMFMAC_COUNTRY_BUF_SZ 4
+
+
+/*
+ * Platform specific driver functions and data. Through the platform specific
+ * device data functions and data can be provided to help the brcmfmac driver to
+ * operate with the device in combination with the used platform.
+ */
+
+
+/**
+ * Note: the brcmfmac can be loaded as module or be statically built-in into
+ * the kernel. If built-in then do note that it uses module_init (and
+ * module_exit) routines which equal device_initcall. So if you intend to
+ * create a module with the platform specific data for the brcmfmac and have
+ * it built-in to the kernel then use a higher initcall then device_initcall
+ * (see init.h). If this is not done then brcmfmac will load without problems
+ * but will not pickup the platform data.
+ *
+ * When the driver does not "detect" platform driver data then it will continue
+ * without reporting anything and just assume there is no data needed. Which is
+ * probably true for most platforms.
+ */
+
+/**
+ * enum brcmf_bus_type - Bus type identifier. Currently SDIO, USB and PCIE are
+ * supported.
+ */
+enum brcmf_bus_type {
+ BRCMF_BUSTYPE_SDIO,
+ BRCMF_BUSTYPE_USB,
+ BRCMF_BUSTYPE_PCIE
+};
+
+
+/**
+ * struct brcmfmac_sdio_pd - SDIO Device specific platform data.
+ *
+ * @txglomsz: SDIO txglom size. Use 0 if default of driver is to be
+ * used.
+ * @drive_strength: is the preferred drive_strength to be used for the SDIO
+ * pins. If 0 then a default value will be used. This is
+ * the target drive strength, the exact drive strength
+ * which will be used depends on the capabilities of the
+ * device.
+ * @oob_irq_supported: does the board have support for OOB interrupts. SDIO
+ * in-band interrupts are relatively slow and for having
+ * less overhead on interrupt processing an out of band
+ * interrupt can be used. If the HW supports this then
+ * enable this by setting this field to true and configure
+ * the oob related fields.
+ * @oob_irq_nr,
+ * @oob_irq_flags: the OOB interrupt information. The values are used for
+ * registering the irq using request_irq function.
+ * @broken_sg_support: flag for broken sg list support of SDIO host controller.
+ * Set this to true if the SDIO host controller has higher
+ * align requirement than 32 bytes for each scatterlist
+ * item.
+ * @sd_head_align: alignment requirement for start of data buffer.
+ * @sd_sgentry_align: length alignment requirement for each sg entry.
+ * @reset: This function can get called if the device communication
+ * broke down. This functionality is particularly useful in
+ * case of SDIO type devices. It is possible to reset a
+ * dongle via sdio data interface, but it requires that
+ * this is fully functional. This function is chip/module
+ * specific and this function should return only after the
+ * complete reset has completed.
+ */
+struct brcmfmac_sdio_pd {
+ int txglomsz;
+ unsigned int drive_strength;
+ bool oob_irq_supported;
+ unsigned int oob_irq_nr;
+ unsigned long oob_irq_flags;
+ bool broken_sg_support;
+ unsigned short sd_head_align;
+ unsigned short sd_sgentry_align;
+ void (*reset)(void);
+};
+
+/**
+ * struct brcmfmac_pd_cc_entry - Struct for translating user space country code
+ * (iso3166) to firmware country code and
+ * revision.
+ *
+ * @iso3166: iso3166 alpha 2 country code string.
+ * @cc: firmware country code string.
+ * @rev: firmware country code revision.
+ */
+struct brcmfmac_pd_cc_entry {
+ char iso3166[BRCMFMAC_COUNTRY_BUF_SZ];
+ char cc[BRCMFMAC_COUNTRY_BUF_SZ];
+ s32 rev;
+};
+
+/**
+ * struct brcmfmac_pd_cc - Struct for translating country codes as set by user
+ * space to a country code and rev which can be used by
+ * firmware.
+ *
+ * @table_size: number of entries in table (> 0)
+ * @table: array of 1 or more elements with translation information.
+ */
+struct brcmfmac_pd_cc {
+ int table_size;
+ struct brcmfmac_pd_cc_entry table[];
+};
+
+/**
+ * struct brcmfmac_pd_device - Device specific platform data. (id/rev/bus_type)
+ * is the unique identifier of the device.
+ *
+ * @id: ID of the device for which this data is. In case of SDIO
+ * or PCIE this is the chipid as identified by chip.c In
+ * case of USB this is the chipid as identified by the
+ * device query.
+ * @rev: chip revision, see id.
+ * @bus_type: The type of bus. Some chipid/rev exist for different bus
+ * types. Each bus type has its own set of settings.
+ * @feature_disable: Bitmask of features to disable (override), See feature.c
+ * in brcmfmac for details.
+ * @country_codes: If available, pointer to struct for translating country
+ * codes.
+ * @bus: Bus specific (union) device settings. Currently only
+ * SDIO.
+ */
+struct brcmfmac_pd_device {
+ unsigned int id;
+ unsigned int rev;
+ enum brcmf_bus_type bus_type;
+ unsigned int feature_disable;
+ struct brcmfmac_pd_cc *country_codes;
+ union {
+ struct brcmfmac_sdio_pd sdio;
+ } bus;
+};
+
+/**
+ * struct brcmfmac_platform_data - BRCMFMAC specific platform data.
+ *
+ * @power_on: This function is called by the brcmfmac driver when the module
+ * gets loaded. This can be particularly useful for low power
+ * devices. The platform spcific routine may for example decide to
+ * power up the complete device. If there is no use-case for this
+ * function then provide NULL.
+ * @power_off: This function is called by the brcmfmac when the module gets
+ * unloaded. At this point the devices can be powered down or
+ * otherwise be reset. So if an actual power_off is not supported
+ * but reset is supported by the devices then reset the devices
+ * when this function gets called. This can be particularly useful
+ * for low power devices. If there is no use-case for this
+ * function then provide NULL.
+ */
+struct brcmfmac_platform_data {
+ void (*power_on)(void);
+ void (*power_off)(void);
+ char *fw_alternative_path;
+ int device_count;
+ struct brcmfmac_pd_device devices[];
+};
+
+
+#endif /* _LINUX_BRCMFMAC_PLATFORM_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/ssb/ssb_regs.h b/sys/compat/linuxkpi/common/include/linux/ssb/ssb_regs.h
new file mode 100644
index 000000000000..e1c18b6b632a
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/linux/ssb/ssb_regs.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2025 Bjoern A. Zeeb
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef _LINUXKPI_LINUX_SSB_SSB_REGS_H
+#define _LINUXKPI_LINUX_SSB_SSB_REGS_H
+
+#define SSB_IDHIGH_RCHI 0x00007000
+#define SSB_IDHIGH_RCHI_SHIFT 8
+#define SSB_IDHIGH_RCLO 0x0000000F
+#define SSB_IDLOW_INITIATOR 0x00000080
+#define SSB_IMSTATE_BUSY 0x01800000
+#define SSB_IMSTATE_IBE 0x00020000
+#define SSB_IMSTATE_REJECT 0x02000000
+#define SSB_IMSTATE_TO 0x00040000
+#define SSB_TMSHIGH_BUSY 0x00000004
+#define SSB_TMSHIGH_SERR 0x00000001
+#define SSB_TMSLOW_CLOCK 0x00010000
+#define SSB_TMSLOW_FGC 0x00020000
+#define SSB_TMSLOW_REJECT 0x00000002
+#define SSB_TMSLOW_RESET 0x00000001
+
+#endif /* _LINUXKPI_LINUX_SSB_SSB_REGS_H */
diff --git a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/cfg80211.c b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/cfg80211.c
index 8af402555b5e..35f68b370714 100644
--- a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -5,13 +5,21 @@
/* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
+#if defined(__FreeBSD__)
+#include <net/cfg80211.h>
+#endif
#include <linux/kernel.h>
#include <linux/etherdevice.h>
#include <linux/module.h>
#include <linux/vmalloc.h>
+#if defined(__linux__)
#include <net/cfg80211.h>
+#endif
#include <net/netlink.h>
#include <uapi/linux/if_arp.h>
+#if defined(__FreeBSD__)
+#include <linux/delay.h>
+#endif
#include <brcmu_utils.h>
#include <defs.h>
@@ -36,6 +44,24 @@
#define BRCMF_SCAN_IE_LEN_MAX 2048
+#if defined(__FreeBSD__)
+#ifdef WPA_OUI
+#undef WPA_OUI
+#endif
+#ifdef WPA_OUI_TYPE
+#undef WPA_OUI_TYPE
+#endif
+#ifdef RSN_OUI
+#undef RSN_OUI
+#endif
+#ifdef WME_OUI_TYPE
+#undef WME_OUI_TYPE
+#endif
+#ifdef WPS_OUI_TYPE
+#undef WPS_OUI_TYPE
+#endif
+#endif
+
#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
#define WPA_OUI_TYPE 1
#define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
@@ -257,7 +283,11 @@ struct brcmf_vs_tlv {
};
struct parsed_vndr_ie_info {
+#if defined(__linux__)
u8 *ie_ptr;
+#elif defined(__FreeBSD__)
+ const u8 *ie_ptr;
+#endif
u32 ie_len; /* total length including id & length field */
struct brcmf_vs_tlv vndrie;
};
@@ -429,7 +459,11 @@ brcmf_parse_tlvs(const void *buf, int buflen, uint key)
if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
return elt;
+#if defined(__linux__)
elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
+#elif defined(__FreeBSD__)
+ elt = (const struct brcmf_tlv *)((const u8 *)elt + (len + TLV_HDR_LEN));
+#endif
totlen -= (len + TLV_HDR_LEN);
}
@@ -462,7 +496,11 @@ brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
return false;
}
+#if defined(__linux__)
static struct brcmf_vs_tlv *
+#elif defined(__FreeBSD__)
+static const struct brcmf_vs_tlv *
+#endif
brcmf_find_wpaie(const u8 *parse, u32 len)
{
const struct brcmf_tlv *ie;
@@ -470,20 +508,34 @@ brcmf_find_wpaie(const u8 *parse, u32 len)
while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
+#if defined(__linux__)
return (struct brcmf_vs_tlv *)ie;
+#elif defined(__FreeBSD__)
+ return (const struct brcmf_vs_tlv *)ie;
+#endif
}
return NULL;
}
+#if defined(__linux__)
static struct brcmf_vs_tlv *
+#elif defined(__FreeBSD__)
+static const struct brcmf_vs_tlv *
+#endif
brcmf_find_wpsie(const u8 *parse, u32 len)
{
const struct brcmf_tlv *ie;
while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
+#if defined(__linux__)
if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
return (struct brcmf_vs_tlv *)ie;
+#elif defined(__FreeBSD__)
+ if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
+ WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
+ return (const struct brcmf_vs_tlv *)ie;
+#endif
}
return NULL;
}
@@ -1239,8 +1291,13 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
reqid = brcmf_pno_find_reqid_by_bucket(cfg->pno,
bucket);
if (!aborted) {
+#if defined(__linux__)
brcmf_dbg(SCAN, "report results: reqid=%llu\n",
reqid);
+#elif defined(__FreeBSD__)
+ brcmf_dbg(SCAN, "report results: reqid=%ju\n",
+ (uintmax_t)reqid);
+#endif
cfg80211_sched_scan_results(cfg_to_wiphy(cfg),
reqid);
}
@@ -2413,7 +2470,11 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
ie = NULL;
ie_len = 0;
/* find the WPA_IE */
+#if defined(__linux__)
wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
+#elif defined(__FreeBSD__)
+ wpa_ie = brcmf_find_wpaie(sme->ie, sme->ie_len);
+#endif
if (wpa_ie) {
ie = wpa_ie;
ie_len = wpa_ie->len + TLV_HDR_LEN;
@@ -2450,7 +2511,11 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
chanspec = 0;
}
+#if defined(__linux__)
brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
+#elif defined(__FreeBSD__)
+ brcmf_dbg(INFO, "ie (%p), ie_len (%u)\n", sme->ie, sme->ie_len);
+#endif
err = brcmf_set_wpa_version(ndev, sme);
if (err) {
@@ -2840,7 +2905,11 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
key = &ifp->vif->profile.key[key_idx];
memset(key, 0, sizeof(*key));
if ((ext_key) && (!is_multicast_ether_addr(mac_addr)))
+#if defined(__linux__)
memcpy((char *)&key->ea, (void *)mac_addr, ETH_ALEN);
+#elif defined(__FreeBSD__)
+ memcpy((char *)&key->ea, mac_addr, ETH_ALEN);
+#endif
key->len = params->key_len;
key->index = key_idx;
memcpy(key->data, params->key, key->len);
@@ -2849,9 +2918,15 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
if (params->seq && params->seq_len == 6) {
/* rx iv */
+#if defined(__linux__)
u8 *ivptr;
ivptr = (u8 *)params->seq;
+#elif defined(__FreeBSD__)
+ const u8 *ivptr;
+
+ ivptr = params->seq;
+#endif
key->rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
(ivptr[3] << 8) | ivptr[2];
key->rxiv.lo = (ivptr[1] << 8) | ivptr[0];
@@ -3758,8 +3833,13 @@ brcmf_alloc_internal_escan_request(struct wiphy *wiphy, u32 n_netinfo) {
req = kzalloc(req_size, GFP_KERNEL);
if (req) {
req->wiphy = wiphy;
+#if defined(__linux__)
req->ssids = (void *)(&req->channels[0]) +
n_netinfo * sizeof(req->channels[0]);
+#elif defined(__FreeBSD__)
+ req->ssids = (void *)((&req->channels[0]) +
+ n_netinfo * sizeof(req->channels[0]));
+#endif
}
return req;
}
@@ -3902,7 +3982,11 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
}
netinfo_start = brcmf_get_netinfo_array(pfn_result);
+#if defined(__linux__)
datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result);
+#elif defined(__FreeBSD__)
+ datalen = e->datalen - ((u8 *)netinfo_start - (u8 *)pfn_result);
+#endif
if (datalen < result_count * sizeof(*netinfo)) {
bphy_err(drvr, "insufficient event data\n");
goto out_err;
@@ -3992,7 +4076,11 @@ static __always_inline void brcmf_delay(u32 ms)
cond_resched();
mdelay(ms);
} else {
+#if defined(__linux__)
msleep(ms);
+#elif defined(__FreeBSD__)
+ linux_msleep(ms);
+#endif
}
}
@@ -4529,7 +4617,11 @@ static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
return 0;
}
+#if defined(__linux__)
static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
+#elif defined(__FreeBSD__)
+static bool brcmf_valid_wpa_oui(const u8 *oui, bool is_rsn_ie)
+#endif
{
if (is_rsn_ie)
return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
@@ -4553,7 +4645,11 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
u32 gval = 0;
u32 wpa_auth = 0;
u32 offset;
+#if defined(__linux__)
u8 *data;
+#elif defined(__FreeBSD__)
+ const u8 *data;
+#endif
u16 rsn_cap;
u32 wme_bss_disable;
u32 mfp;
@@ -4563,7 +4659,11 @@ brcmf_configure_wpaie(struct brcmf_if *ifp,
goto exit;
len = wpa_ie->len + TLV_HDR_LEN;
+#if defined(__linux__)
data = (u8 *)wpa_ie;
+#elif defined(__FreeBSD__)
+ data = (const u8 *)wpa_ie;
+#endif
offset = TLV_HDR_LEN;
if (!is_rsn_ie)
offset += VS_IE_FIXED_HDR_LEN;
@@ -4786,19 +4886,32 @@ static s32
brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
struct parsed_vndr_ies *vndr_ies)
{
+#if defined(__linux__)
struct brcmf_vs_tlv *vndrie;
struct brcmf_tlv *ie;
+#elif defined(__FreeBSD__)
+ const struct brcmf_vs_tlv *vndrie;
+ const struct brcmf_tlv *ie;
+#endif
struct parsed_vndr_ie_info *parsed_info;
s32 remaining_len;
remaining_len = (s32)vndr_ie_len;
memset(vndr_ies, 0, sizeof(*vndr_ies));
+#if defined(__linux__)
ie = (struct brcmf_tlv *)vndr_ie_buf;
+#elif defined(__FreeBSD__)
+ ie = (const struct brcmf_tlv *)vndr_ie_buf;
+#endif
while (ie) {
if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
goto next;
+#if defined(__linux__)
vndrie = (struct brcmf_vs_tlv *)ie;
+#elif defined(__FreeBSD__)
+ vndrie = (const struct brcmf_vs_tlv *)ie;
+#endif
/* len should be bigger than OUI length + one */
if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
brcmf_err("invalid vndr ie. length is too small %d\n",
@@ -4816,7 +4929,11 @@ brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
parsed_info = &vndr_ies->ie_info[vndr_ies->count];
/* save vndr ie information */
+#if defined(__linux__)
parsed_info->ie_ptr = (char *)vndrie;
+#elif defined(__FreeBSD__)
+ parsed_info->ie_ptr = (const char *)vndrie;
+#endif
parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
@@ -4833,14 +4950,22 @@ next:
if (remaining_len <= TLV_HDR_LEN)
ie = NULL;
else
+#if defined(__linux__)
ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
+#elif defined(__FreeBSD__)
+ ie = (const struct brcmf_tlv *)(((const u8 *)ie) + ie->len +
+#endif
TLV_HDR_LEN);
}
return 0;
}
static u32
+#if defined(__linux__)
brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
+#elif defined(__FreeBSD__)
+brcmf_vndr_ie(u8 *iebuf, s32 pktflag, const u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
+#endif
{
strscpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN);
@@ -5085,11 +5210,19 @@ brcmf_parse_configure_security(struct brcmf_if *ifp,
s32 err = 0;
/* find the RSN_IE */
+#if defined(__linux__)
rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
+#elif defined(__FreeBSD__)
+ rsn_ie = brcmf_parse_tlvs(settings->beacon.tail,
+#endif
settings->beacon.tail_len, WLAN_EID_RSN);
/* find the WPA_IE */
+#if defined(__linux__)
wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
+#elif defined(__FreeBSD__)
+ wpa_ie = brcmf_find_wpaie(settings->beacon.tail,
+#endif
settings->beacon.tail_len);
if (wpa_ie || rsn_ie) {
@@ -5100,9 +5233,16 @@ brcmf_parse_configure_security(struct brcmf_if *ifp,
if (err < 0)
return err;
} else {
+#if defined(__linux__)
struct brcmf_vs_tlv *tmp_ie;
tmp_ie = (struct brcmf_vs_tlv *)rsn_ie;
+#elif defined(__FreeBSD__)
+ const struct brcmf_vs_tlv *tmp_ie;
+
+ tmp_ie = (const struct brcmf_vs_tlv *)rsn_ie;
+#endif
+
/* RSN IE */
err = brcmf_configure_wpaie(ifp, tmp_ie, true);
@@ -5155,7 +5295,11 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
&ifp->vif->is_11d)) {
is_11d = supports_11d = false;
} else {
+#if defined(__linux__)
country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
+#elif defined(__FreeBSD__)
+ country_ie = brcmf_parse_tlvs(settings->beacon.tail,
+#endif
settings->beacon.tail_len,
WLAN_EID_COUNTRY);
is_11d = country_ie ? 1 : 0;
@@ -5166,7 +5310,11 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
if (settings->ssid == NULL || settings->ssid_len == 0) {
ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
ssid_ie = brcmf_parse_tlvs(
+#if defined(__linux__)
(u8 *)&settings->beacon.head[ie_offset],
+#elif defined(__FreeBSD__)
+ &settings->beacon.head[ie_offset],
+#endif
settings->beacon.head_len - ie_offset,
WLAN_EID_SSID);
if (!ssid_ie || ssid_ie->len > IEEE80211_MAX_SSID_LEN)
@@ -5382,7 +5530,11 @@ static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev,
if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
/* Due to most likely deauths outstanding we sleep */
/* first to make sure they get processed by fw. */
+#if defined(__linux__)
msleep(400);
+#elif defined(__FreeBSD__)
+ linux_msleep(400);
+#endif
if (profile->use_fwauth != BIT(BRCMF_PROFILE_FWAUTH_NONE)) {
struct cfg80211_crypto_settings crypto = {};
@@ -5504,10 +5656,18 @@ brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
+#if defined(__linux__)
(void *)mac, ETH_ALEN);
+#elif defined(__FreeBSD__)
+ __DECONST(u8 *, mac), ETH_ALEN);
+#endif
else
err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
+#if defined(__linux__)
(void *)mac, ETH_ALEN);
+#elif defined(__FreeBSD__)
+ __DECONST(u8 *, mac), ETH_ALEN);
+#endif
if (err < 0)
bphy_err(drvr, "Setting SCB (de-)authorize failed, %d\n", err);
@@ -5623,8 +5783,13 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
le16_to_cpu(action_frame->len));
+#if defined(__linux__)
brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, channel=%d\n",
*cookie, le16_to_cpu(action_frame->len),
+#elif defined(__FreeBSD__)
+ brcmf_dbg(TRACE, "Action frame, cookie=%ju, len=%d, channel=%d\n",
+ (uintmax_t)*cookie, le16_to_cpu(action_frame->len),
+#endif
le32_to_cpu(af_params->channel));
ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
@@ -5815,11 +5980,19 @@ brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
break;
case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
brcmf_dbg(TRACE, "TDLS Peer Connected\n");
+#if defined(__linux__)
brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
+#elif defined(__FreeBSD__)
+ brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, e->addr);
+#endif
break;
case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
+#if defined(__linux__)
brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
+#elif defined(__FreeBSD__)
+ brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, e->addr);
+#endif
break;
}
@@ -6553,7 +6726,11 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
(e->event_code == BRCMF_E_DEAUTH_IND) ||
(e->event_code == BRCMF_E_DISASSOC_IND) ||
((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
+#if defined(__linux__)
brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
+#elif defined(__FreeBSD__)
+ brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, e->addr);
+#endif
}
if (brcmf_is_apmode(ifp->vif)) {
@@ -6640,7 +6817,11 @@ brcmf_notify_mic_status(struct brcmf_if *ifp,
else
key_type = NL80211_KEYTYPE_PAIRWISE;
+#if defined(__linux__)
cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
+#elif defined(__FreeBSD__)
+ cfg80211_michael_mic_failure(ifp->ndev, e->addr, key_type, -1,
+#endif
NULL, GFP_KERNEL);
return 0;
@@ -8183,7 +8364,11 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
goto exit;
/* Add 10 ms for IOVAR completion */
+#if defined(__linux__)
msleep(ACS_MSRMNT_DELAY + 10);
+#elif defined(__FreeBSD__)
+ linux_msleep(ACS_MSRMNT_DELAY + 10);
+#endif
/* Issue IOVAR to collect measurement results */
req.msrmnt_query = 1;
@@ -8204,8 +8389,13 @@ brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
brcmf_dbg(INFO, "OBSS dump: channel %d: survey duration %d\n",
ieee80211_frequency_to_channel(info->channel->center_freq),
ACS_MSRMNT_DELAY);
+#if defined(__linux__)
brcmf_dbg(INFO, "noise(%d) busy(%llu) rx(%llu) tx(%llu)\n",
info->noise, info->time_busy, info->time_rx, info->time_tx);
+#elif defined(__FreeBSD__)
+ brcmf_dbg(INFO, "noise(%d) busy(%ju) rx(%ju) tx(%ju)\n",
+ info->noise, (uintmax_t)info->time_busy, (uintmax_t)info->time_rx, (uintmax_t)info->time_tx);
+#endif
exit:
if (!brcmf_is_apmode(ifp->vif))
diff --git a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/common.c b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/common.c
index 688f16c51319..17e408b7fa23 100644
--- a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/common.c
+++ b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/common.c
@@ -3,6 +3,10 @@
* Copyright (c) 2010 Broadcom Corporation
*/
+#if defined(__FreeBSD__)
+#define LINUXKPI_PARAM_PREFIX brcmfmac_
+#endif
+
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/netdevice.h>
@@ -24,6 +28,12 @@
MODULE_AUTHOR("Broadcom Corporation");
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
MODULE_LICENSE("Dual BSD/GPL");
+#if defined(__FreeBSD__)
+MODULE_DEPEND(brcmfmac, brcmutil, 1, 1, 1);
+MODULE_DEPEND(brcmfmac, linuxkpi, 1, 1, 1);
+MODULE_DEPEND(brcmfmac, linuxkpi_wlan, 1, 1, 1);
+MODULE_DEPEND(brcmfmac, lindebugfs, 1, 1, 1); /* XXX-BZ someone should fix this */
+#endif
#define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40
#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
@@ -118,7 +128,11 @@ static int brcmf_c_download(struct brcmf_if *ifp, u16 flag,
}
static int brcmf_c_download_blob(struct brcmf_if *ifp,
+#if defined(__linux__)
const void *data, size_t size,
+#elif defined(__FreeBSD__)
+ const u8 *data, size_t size,
+#endif
const char *loadvar, const char *statvar)
{
struct brcmf_pub *drvr = ifp->drvr;
@@ -467,10 +481,22 @@ void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...)
vaf.fmt = fmt;
vaf.va = &args;
+#if defined(__linux__)
if (bus)
dev_err(bus->dev, "%s: %pV", func, &vaf);
else
pr_err("%s: %pV", func, &vaf);
+#elif defined(__FreeBSD__)
+ {
+ char *str;
+ vasprintf(&str, M_KMALLOC, vaf.fmt, args);
+ if (bus)
+ dev_err(bus->dev, "ERROR: %s: %s", func, str);
+ else
+ pr_err("ERROR: %s: %s", func, str);
+ free(str, M_KMALLOC);
+ }
+#endif
va_end(args);
}
@@ -487,7 +513,16 @@ void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
va_start(args, fmt);
vaf.va = &args;
if (brcmf_msg_level & level)
+#if defined(__linux__)
pr_debug("%s %pV", func, &vaf);
+#elif defined(__FreeBSD__)
+ {
+ char *str;
+ vasprintf(&str, M_KMALLOC, vaf.fmt, args);
+ pr_debug("%s %s", func, str);
+ free(str, M_KMALLOC);
+ }
+#endif
trace_brcmf_dbg(level, func, &vaf);
va_end(args);
}
diff --git a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/commonring.c b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/commonring.c
index e44236cb210e..c0880fa12f57 100644
--- a/sys/contrib/dev/broadcom/brcm80211/brcmfmac/commonring.c
+++ b/sys/contrib/dev/broadcom/brcm80211/brcmfmac/commonring.c
@@ -119,8 +119,13 @@ again:
available = commonring->r_ptr - commonring->w_ptr;
if (available > 1) {
+#if defined(__linux__)
ret_ptr = commonring->buf_addr +
(commonring->w_ptr * commonring->item_len);
+#elif defined(__FreeBSD__)
+ ret_ptr = (void *)((uintptr_t)commonring->buf_addr +
+ (commonring->w_ptr * commonring->item_len));
+#endif
commonring->w_ptr++;
if (commonring->w_ptr == commonring->depth)
commonring->w_ptr = 0;
@@ -155,8 +160,13 @@ again:
available = commonring->r_ptr - commonring->w_ptr;
if (available > 1) {
+#if defined(__linux__)
ret_ptr = commonring->buf_addr +
(commonring->w_ptr * commonring->item_len);
+#elif defined(__FreeBSD__)
+ ret_ptr = (void *)((uintptr_t)commonring->buf_addr +
+ (commonring->w_ptr * commonring->item_len));
+#endif
*alloced = min_t(u16, n_items, available - 1);
if (*alloced + commonring->w_ptr > commonring->depth)
*alloced = commonring->depth - commonring->w_ptr;
@@ -217,8 +227,13 @@ void *brcmf_commonring_get_read_ptr(struct brcmf_commonring *commonring,
if (*n_items == 0)
return NULL;
+#if defined(__linux__)
return commonring->buf_addr +
(commonring->r_ptr * commonring->item_len);
+#elif defined(__FreeBSD__)
*** 1217 LINES SKIPPED ***