git: 2e183d999c60 - main - LinuxKPI: 802.11 header updates and add/adjust source dependencies.

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Wed, 16 Feb 2022 00:38:27 UTC
The branch main has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=2e183d999c6033e876602ddbbc5cb538bb41e4b3

commit 2e183d999c6033e876602ddbbc5cb538bb41e4b3
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2022-02-15 23:45:15 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2022-02-15 23:45:15 +0000

    LinuxKPI: 802.11 header updates and add/adjust source dependencies.
    
    This update is for more/newer versions of drivers:
    - add and properly place more structs, enums, defines needed by drivers.
    - correct types of struct fields.
    - make various function arguments const.
    - move REG_RULE() macro to its own file regulatory.h and
      use macros for calculations.
    - add linuxkpi_ieee80211_get_channel() implementation.
    - change linuxkpi_ieee80211_ifattach() to return int for error checking.
    
    No intended functional changes for iwlwifi.
    
    Sponsored by:   The FreeBSD Foundation (partially)
    MFC after:      3 days
---
 .../linuxkpi/common/include/linux/ieee80211.h      |  37 ++++++
 sys/compat/linuxkpi/common/include/linux/nl80211.h |  49 +++++++-
 sys/compat/linuxkpi/common/include/net/cfg80211.h  | 139 ++++++++++++++-------
 sys/compat/linuxkpi/common/include/net/mac80211.h  | 113 ++++++++++++-----
 .../linuxkpi/common/include/net/regulatory.h       |  45 +++++++
 sys/compat/linuxkpi/common/src/linux_80211.c       |  34 ++++-
 6 files changed, 339 insertions(+), 78 deletions(-)

diff --git a/sys/compat/linuxkpi/common/include/linux/ieee80211.h b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
index 1fe295c2ae96..4b8c3243b26a 100644
--- a/sys/compat/linuxkpi/common/include/linux/ieee80211.h
+++ b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
@@ -42,10 +42,22 @@
 extern int debug_80211;
 
 
+/* 9.4.2.55 Management MIC element (CMAC-256, GMAC-128, and GMAC-256). */
+struct ieee80211_mmie_16 {
+	uint8_t		element_id;
+	uint8_t		length;
+	uint16_t	key_id;
+	uint8_t		ipn[6];
+	uint8_t		mic[16];
+};
+
 #define	IEEE80211_CCMP_HDR_LEN			8	/* 802.11i .. net80211 comment */
 #define	IEEE80211_CCMP_PN_LEN			6
 #define	IEEE80211_CCMP_MIC_LEN			8	/* || 16 */
+#define	IEEE80211_CCMP_256_HDR_LEN		8
+#define	IEEE80211_CCMP_256_MIC_LEN		16
 #define	IEEE80211_GCMP_HDR_LEN			8
+#define	IEEE80211_GCMP_MIC_LEN			16
 #define	IEEE80211_GCMP_PN_LEN			6
 #define	IEEE80211_GMAC_PN_LEN			6
 
@@ -56,6 +68,7 @@ extern int debug_80211;
 #define	IEEE80211_MAX_AMPDU_BUF_HT		0x40
 #define	IEEE80211_MAX_AMPDU_BUF			256	/* for HE? */
 
+#define	IEEE80211_MAX_FRAME_LEN			2352
 #define	IEEE80211_MAX_DATA_LEN			(2300 + IEEE80211_CRC_LEN)
 
 #define	IEEE80211_MAX_MPDU_LEN_HT_BA		4095	/* 9.3.2.1 Format of Data frames; non-VHT non-DMG STA */
@@ -73,6 +86,7 @@ extern int debug_80211;
 #define	IEEE80211_P2P_OPPPS_ENABLE_BIT		BIT(7)
 
 #define	IEEE80211_QOS_CTL_TAG1D_MASK		0x0007
+#define	IEEE80211_QOS_CTL_TID_MASK		IEEE80211_QOS_TID
 #define	IEEE80211_QOS_CTL_EOSP			0x0010
 #define	IEEE80211_QOS_CTL_A_MSDU_PRESENT	0x0080	/* 9.2.4.5.1, Table 9-6 QoS Control Field */
 
@@ -82,6 +96,7 @@ enum ieee80211_rate_control_changed_flags {
 	IEEE80211_RC_BW_CHANGED			= BIT(0),
 	IEEE80211_RC_NSS_CHANGED		= BIT(1),
 	IEEE80211_RC_SUPP_RATES_CHANGED		= BIT(2),
+	IEEE80211_RC_SMPS_CHANGED		= BIT(3),
 };
 
 #define	IEEE80211_SCTL_FRAG			IEEE80211_SEQ_FRAG_MASK
@@ -102,10 +117,18 @@ enum ieee80211_rate_control_changed_flags {
 #define	WLAN_CAPABILITY_SHORT_PREAMBLE		__LINE__ /* TODO FIXME brcmfmac */
 #define	WLAN_CAPABILITY_SHORT_SLOT_TIME		__LINE__ /* TODO FIXME brcmfmac */
 
+enum wlan_ht_cap_sm_ps {
+	WLAN_HT_CAP_SM_PS_STATIC		= 0,
+	WLAN_HT_CAP_SM_PS_DYNAMIC,
+	WLAN_HT_CAP_SM_PS_INVALID,
+	WLAN_HT_CAP_SM_PS_DISABLED,
+};
 
 #define	WLAN_MAX_KEY_LEN			32 /* TODO FIXME brcmfmac */
 #define	WLAN_PMKID_LEN				16 /* TODO FIXME brcmfmac */
 
+#define	WLAN_KEY_LEN_WEP40			5
+#define	WLAN_KEY_LEN_WEP104			13
 #define	WLAN_KEY_LEN_CCMP			16
 #define	WLAN_KEY_LEN_GCMP_256			32
 
@@ -113,14 +136,17 @@ enum ieee80211_rate_control_changed_flags {
 enum ieee80211_min_mpdu_start_spacing {
 	IEEE80211_HT_MPDU_DENSITY_NONE		= 0,
 	IEEE80211_HT_MPDU_DENSITY_4		= 5,	/* 4us */
+	IEEE80211_HT_MPDU_DENSITY_8		= 6,	/* 8us */
 	IEEE80211_HT_MPDU_DENSITY_16		= 7, 	/* 16us */
 };
 
 /* 9.4.2.57, Table 9-168, HT Operation element fields and subfields */
 #define	IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT	0x0080	/* B24.. */
 
+#define	IEEE80211_FCTL_FTYPE			IEEE80211_FC0_TYPE_MASK
 #define	IEEE80211_FCTL_STYPE			IEEE80211_FC0_SUBTYPE_MASK
 #define	IEEE80211_FCTL_ORDER			(IEEE80211_FC1_ORDER << 8)
+#define	IEEE80211_FCTL_PROTECTED		(IEEE80211_FC1_PROTECTED << 8)
 
 #define	IEEE80211_STYPE_ASSOC_REQ		IEEE80211_FC0_SUBTYPE_ASSOC_REQ
 #define	IEEE80211_STYPE_REASSOC_REQ		IEEE80211_FC0_SUBTYPE_REASSOC_REQ
@@ -129,6 +155,7 @@ enum ieee80211_min_mpdu_start_spacing {
 #define	IEEE80211_STYPE_AUTH			IEEE80211_FC0_SUBTYPE_AUTH
 #define	IEEE80211_STYPE_DEAUTH			IEEE80211_FC0_SUBTYPE_DEAUTH
 #define	IEEE80211_STYPE_ACTION			IEEE80211_FC0_SUBTYPE_ACTION
+#define	IEEE80211_STYPE_QOS_DATA		IEEE80211_FC0_SUBTYPE_QOS
 
 #define	IEEE80211_NUM_ACS			4	/* net8021::WME_NUM_AC */
 
@@ -205,6 +232,8 @@ struct ieee80211_vht_cap {
 	__le32					vht_cap_info;
 };
 
+#define	IEEE80211_HT_MAX_AMPDU_FACTOR		13
+
 enum ieee80211_ht_max_ampdu_len {
 	IEEE80211_HT_MAX_AMPDU_64K
 };
@@ -231,6 +260,7 @@ enum ieee80211_chanctx_change_flags {
 	IEEE80211_CHANCTX_CHANGE_RADAR		= BIT(1),
 	IEEE80211_CHANCTX_CHANGE_RX_CHAINS	= BIT(2),
 	IEEE80211_CHANCTX_CHANGE_WIDTH		= BIT(3),
+	IEEE80211_CHANCTX_CHANGE_CHANNEL	= BIT(4),
 };
 
 enum ieee80211_frame_release_type {
@@ -243,6 +273,7 @@ enum ieee80211_p2p_attr_ids {
 	IEEE80211_P2P_ATTR_DEVICE_INFO,
 	IEEE80211_P2P_ATTR_GROUP_ID,
 	IEEE80211_P2P_ATTR_LISTEN_CHANNEL,
+	IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
 };
 
 enum ieee80211_reconfig_type {
@@ -294,6 +325,10 @@ enum ieee80211_tx_info_flags {
 	IEEE80211_TX_STAT_AMPDU_NO_BACK		= BIT(9),
 	IEEE80211_TX_STAT_TX_FILTERED		= BIT(10),
 	IEEE80211_TX_STAT_NOACK_TRANSMITTED	= BIT(11),
+	IEEE80211_TX_CTL_FIRST_FRAGMENT		= BIT(12),
+	IEEE80211_TX_INTFL_DONT_ENCRYPT		= BIT(13),
+	IEEE80211_TX_CTL_NO_CCK_RATE		= BIT(14),
+	IEEE80211_TX_CTL_INJECTED		= BIT(15),
 };
 
 enum ieee80211_tx_control_flags {
@@ -310,6 +345,7 @@ enum ieee80211_tx_rate_flags {
 	IEEE80211_TX_RC_MCS			= BIT(4),
 	IEEE80211_TX_RC_SHORT_GI		= BIT(5),
 	IEEE80211_TX_RC_VHT_MCS			= BIT(6),
+	IEEE80211_TX_RC_USE_SHORT_PREAMBLE	= BIT(7),
 };
 
 #define	IEEE80211_HT_CTL_LEN	4
@@ -414,6 +450,7 @@ enum ieee80211_reason_code {
 	/* reserved				= 0, */
 	WLAN_REASON_UNSPECIFIED			= 1,
 	WLAN_REASON_DEAUTH_LEAVING		= 3,	/* LEAVING_NETWORK_DEAUTH */
+	WLAN_REASON_TDLS_TEARDOWN_UNREACHABLE	= 25,
 	WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED	= 26,
 };
 
diff --git a/sys/compat/linuxkpi/common/include/linux/nl80211.h b/sys/compat/linuxkpi/common/include/linux/nl80211.h
index d9d9ba4edba9..3a97879e2fd4 100644
--- a/sys/compat/linuxkpi/common/include/linux/nl80211.h
+++ b/sys/compat/linuxkpi/common/include/linux/nl80211.h
@@ -50,6 +50,7 @@ enum nl80211_feature_flags {
 	NL80211_FEATURE_TDLS_CHANNEL_SWITCH		= BIT(13),
 	NL80211_FEATURE_TX_POWER_INSERTION		= BIT(14),
 	NL80211_FEATURE_WFA_TPC_IE_IN_PROBES		= BIT(15),
+	NL80211_FEATURE_AP_SCAN				= BIT(16),
 };
 
 enum nl80211_pmsr_ftm_failure_flags {
@@ -77,6 +78,7 @@ enum nl80211_reg_rule_flags {
 	NL80211_RRF_NO_80MHZ				= BIT(7),
 	NL80211_RRF_NO_160MHZ				= BIT(8),
 	NL80211_RRF_NO_HE				= BIT(9),
+	NL80211_RRF_NO_OFDM				= BIT(10),
 };
 #define	NL80211_RRF_NO_HT40	(NL80211_RRF_NO_HT40MINUS|NL80211_RRF_NO_HT40PLUS)
 
@@ -89,9 +91,6 @@ enum nl80211_scan_flags {
 	NL80211_SCAN_FLAG_RANDOM_SN			= BIT(5),
 };
 
-#define	NL80211_REGDOM_SET_BY_USER			1
-#define	NL80211_REGDOM_SET_BY_DRIVER			2
-
 #define	NL80211_MAX_SUPP_REG_RULES			512	/* TODO FIXME, random */
 
 #define	NL80211_BSS_CHAN_WIDTH_20			__LINE__ /* TODO FIXME, brcmfmac */
@@ -210,6 +209,11 @@ enum nl80211_ext_feature {
 	NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK,
 	NL80211_EXT_FEATURE_BEACON_PROTECTION_CLIENT,
 	NL80211_EXT_FEATURE_SCAN_RANDOM_SN,
+	NL80211_EXT_FEATURE_STA_TX_PWR,
+	NL80211_EXT_FEATURE_CQM_RSSI_LIST,
+	NL80211_EXT_FEATURE_AQL,
+	NL80211_EXT_FEATURE_AIRTIME_FAIRNESS,
+	NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT,
 
 	/* Keep this last. */
 	NUM_NL80211_EXT_FEATURES
@@ -234,6 +238,8 @@ enum nl80211_sta_info {
 	NL80211_STA_INFO_TX_PACKETS,
 	NL80211_STA_INFO_TX_BYTES,
 	NL80211_STA_INFO_TX_FAILED,
+	NL80211_STA_INFO_TX_RETRIES,
+	NL80211_STA_INFO_RX_DURATION,
 };
 
 enum nl80211_ftm_stats {
@@ -251,7 +257,10 @@ enum nl80211_ftm_stats {
 
 enum nl80211_reg_initiator {
 	/* XXX TODO */
-	_XXX_FXIME_RTW88_USES_ENUM,
+	NL80211_REGDOM_SET_BY_USER,
+	NL80211_REGDOM_SET_BY_DRIVER,
+	NL80211_REGDOM_SET_BY_CORE,
+	NL80211_REGDOM_SET_BY_COUNTRY_IE,
 };
 
 struct nl80211_sta_flag_update {
@@ -311,4 +320,36 @@ enum nl80211_sar_type {
 	NL80211_SAR_TYPE_POWER,
 };
 
+#define	NL80211_VHT_NSS_MAX			8
+
+enum nl80211_tid_cfg_attr {
+	NL80211_TID_CONFIG_ATTR_NOACK,
+	NL80211_TID_CONFIG_ATTR_RETRY_SHORT,
+	NL80211_TID_CONFIG_ATTR_TX_RATE_TYPE,
+	NL80211_TID_CONFIG_ATTR_TX_RATE,
+	NL80211_TID_CONFIG_ATTR_RTSCTS_CTRL,
+	NL80211_TID_CONFIG_ATTR_RETRY_LONG,
+	NL80211_TID_CONFIG_ATTR_AMPDU_CTRL,
+};
+
+enum nl80211_tid_config {
+	NL80211_TID_CONFIG_ENABLE,
+};
+
+enum nl80211_tx_rate_setting {
+	NL80211_TX_RATE_AUTOMATIC,
+	NL80211_TX_RATE_FIXED,
+	NL80211_TX_RATE_LIMITED,
+};
+
+enum nl80211_txrate_gi {
+	NL80211_TXRATE_FORCE_LGI,
+};
+
+enum nl80211_probe_resp_offload_support {
+	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2,
+	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS,
+	NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P,
+};
+
 #endif	/* _LINUXKPI_LINUX_NL80211_H */
diff --git a/sys/compat/linuxkpi/common/include/net/cfg80211.h b/sys/compat/linuxkpi/common/include/net/cfg80211.h
index 8ec051e173a7..d8b852ec7a6d 100644
--- a/sys/compat/linuxkpi/common/include/net/cfg80211.h
+++ b/sys/compat/linuxkpi/common/include/net/cfg80211.h
@@ -36,10 +36,12 @@
 #include <linux/nl80211.h>
 #include <linux/ieee80211.h>
 #include <linux/if_ether.h>
+#include <linux/ethtool.h>
 #include <linux/device.h>
 #include <linux/netdevice.h>
 #include <linux/random.h>
 #include <linux/skbuff.h>
+#include <net/regulatory.h>
 
 /* linux_80211.c */
 extern int debug_80211;
@@ -74,8 +76,18 @@ enum cfg80211_rate_info_flags {
 
 extern const uint8_t rfc1042_header[6];
 
-enum cfg80211_bss_ftypes {
+enum ieee80211_privacy {
+	IEEE80211_PRIVACY_ANY,
+};
+
+enum ieee80211_bss_type {
+	IEEE80211_BSS_TYPE_ANY,
+};
+
+enum cfg80211_bss_frame_type {
 	CFG80211_BSS_FTYPE_UNKNOWN,
+	CFG80211_BSS_FTYPE_BEACON,
+	CFG80211_BSS_FTYPE_PRESP,
 };
 
 enum ieee80211_channel_flags {
@@ -88,6 +100,7 @@ enum ieee80211_channel_flags {
 	IEEE80211_CHAN_NO_HT40PLUS		= BIT(6),
 	IEEE80211_CHAN_NO_80MHZ			= BIT(7),
 	IEEE80211_CHAN_NO_160MHZ		= BIT(8),
+	IEEE80211_CHAN_NO_OFDM			= BIT(9),
 };
 #define	IEEE80211_CHAN_NO_HT40	(IEEE80211_CHAN_NO_HT40MINUS|IEEE80211_CHAN_NO_HT40PLUS)
 
@@ -107,8 +120,30 @@ struct linuxkpi_ieee80211_channel {
 	bool					beacon_found;
 	int     max_antenna_gain, max_reg_power;
 	int     orig_flags;
+	int	dfs_cac_ms, dfs_state;
 };
 
+/* XXX net80211 calls these IEEE80211_HTCAP_* */
+#define	IEEE80211_HT_CAP_LDPC_CODING		0x0001	/* IEEE80211_HTCAP_LDPC */
+#define	IEEE80211_HT_CAP_SUP_WIDTH_20_40	0x0002	/* IEEE80211_HTCAP_CHWIDTH40 */
+#define	IEEE80211_HT_CAP_GRN_FLD		0x0010	/* IEEE80211_HTCAP_GREENFIELD */
+#define	IEEE80211_HT_CAP_SGI_20			0x0020	/* IEEE80211_HTCAP_SHORTGI20 */
+#define	IEEE80211_HT_CAP_SGI_40			0x0040	/* IEEE80211_HTCAP_SHORTGI40 */
+#define	IEEE80211_HT_CAP_TX_STBC		0x0080	/* IEEE80211_HTCAP_TXSTBC */
+#define	IEEE80211_HT_CAP_RX_STBC		0x0100	/* IEEE80211_HTCAP_RXSTBC */
+#define	IEEE80211_HT_CAP_RX_STBC_SHIFT		8	/* IEEE80211_HTCAP_RXSTBC_S */
+#define	IEEE80211_HT_CAP_MAX_AMSDU		0x0800	/* IEEE80211_HTCAP_MAXAMSDU */
+#define	IEEE80211_HT_CAP_DSSSCCK40		0x1000	/* IEEE80211_HTCAP_DSSSCCK40 */
+#define	IEEE80211_HT_CAP_SM_PS			0x000c	/* IEEE80211_HTCAP_SMPS */
+#define	IEEE80211_HT_CAP_SM_PS_SHIFT		2
+#define	IEEE80211_HT_CAP_LSIG_TXOP_PROT		0x8000	/* IEEE80211_HTCAP_LSIGTXOPPROT */
+
+#define	IEEE80211_HT_MCS_TX_DEFINED		0x0001
+#define	IEEE80211_HT_MCS_TX_RX_DIFF		0x0002
+#define	IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT	2
+#define	IEEE80211_HT_MCS_RX_HIGHEST_MASK	0x3FF
+#define	IEEE80211_HT_MCS_MASK_LEN		10
+
 enum ieee80211_vht_mcs_support {
 	LKPI_IEEE80211_VHT_MCS_SUPPORT_0_7,
 	LKPI_IEEE80211_VHT_MCS_SUPPORT_0_8,
@@ -119,11 +154,11 @@ struct cfg80211_bitrate_mask {
 	/* TODO FIXME */
 	/* This is so weird but nothing else works out...*/
 	struct {
-		uint64_t	legacy;		/* XXX? */
-		uint8_t		ht_mcs[16];	/* XXX? */
-		uint16_t	vht_mcs[16];	/* XXX? */
-		uint16_t	he_mcs[16];	/* XXX? */
-		uint8_t		gi;		/* NL80211_TXRATE_FORCE_LGI enum? */
+		uint64_t			legacy;		/* XXX? */
+		uint8_t				ht_mcs[IEEE80211_HT_MCS_MASK_LEN];
+		uint16_t			vht_mcs[16];	/* XXX? */
+		uint16_t			he_mcs[16];	/* XXX? */
+		enum nl80211_txrate_gi		gi;
 	} control[NUM_NL80211_BANDS];
 };
 
@@ -140,30 +175,13 @@ struct ieee80211_rate {
 	uint32_t		flags;
 };
 
-/* XXX net80211 calls these IEEE80211_HTCAP_* */
-#define	IEEE80211_HT_CAP_LDPC_CODING		0x0001	/* IEEE80211_HTCAP_LDPC */
-#define	IEEE80211_HT_CAP_SUP_WIDTH_20_40	0x0002	/* IEEE80211_HTCAP_CHWIDTH40 */
-#define	IEEE80211_HT_CAP_GRN_FLD		0x0010	/* IEEE80211_HTCAP_GREENFIELD */
-#define	IEEE80211_HT_CAP_SGI_20			0x0020	/* IEEE80211_HTCAP_SHORTGI20 */
-#define	IEEE80211_HT_CAP_SGI_40			0x0040	/* IEEE80211_HTCAP_SHORTGI40 */
-#define	IEEE80211_HT_CAP_TX_STBC		0x0080	/* IEEE80211_HTCAP_TXSTBC */
-#define	IEEE80211_HT_CAP_RX_STBC		0x0100	/* IEEE80211_HTCAP_RXSTBC */
-#define	IEEE80211_HT_CAP_RX_STBC_SHIFT		8	/* IEEE80211_HTCAP_RXSTBC_S */
-#define	IEEE80211_HT_CAP_MAX_AMSDU		0x0800	/* IEEE80211_HTCAP_MAXAMSDU */
-#define	IEEE80211_HT_CAP_DSSSCCK40		0x1000	/* IEEE80211_HTCAP_DSSSCCK40 */
-
-#define	IEEE80211_HT_MCS_TX_DEFINED		0x0001
-#define	IEEE80211_HT_MCS_TX_RX_DIFF		0x0002
-#define	IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT	2
-#define	IEEE80211_HT_MCS_RX_HIGHEST_MASK	0x3FF
-
 struct ieee80211_sta_ht_cap {
 		/* TODO FIXME */
 	int	ampdu_density, ampdu_factor;
 	bool		ht_supported;
 	uint16_t	cap;
 	struct mcs {
-		uint16_t	rx_mask[16];	/* XXX ? > 4 (rtw88) */
+		uint16_t	rx_mask[IEEE80211_HT_MCS_MASK_LEN];	/* XXX ? > 4 (rtw88) */
 		int		rx_highest;
 		uint32_t	tx_params;
 	} mcs;
@@ -175,7 +193,9 @@ struct ieee80211_sta_ht_cap {
 #define	IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454	0x00000002	/* IEEE80211_VHTCAP_MAX_MPDU_LENGTH_11454 */
 #define	IEEE80211_VHT_CAP_MAX_MPDU_MASK		0x00000003	/* IEEE80211_VHTCAP_MAX_MPDU_MASK */
 
-#define	IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ	(IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160MHZ << IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK_S)
+#define	IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ		(IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160MHZ << IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK_S)
+#define	IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ	(IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_160_80P80MHZ << IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK_S)
+#define	IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK	0x0000000c	/* IEEE80211_VHTCAP_SUPP_CHAN_WIDTH_MASK */
 
 #define	IEEE80211_VHT_CAP_RXLDPC		0x00000010	/* IEEE80211_VHTCAP_RXLDPC */
 
@@ -196,6 +216,7 @@ struct ieee80211_sta_ht_cap {
 #define	IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE	0x00100000	/* IEEE80211_VHTCAP_MU_BEAMFORMEE_CAPABLE */
 
 #define	IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT		13	/* IEEE80211_VHTCAP_BEAMFORMEE_STS_SHIFT */
+#define	IEEE80211_VHT_CAP_BEAMFORMEE_STS_MASK		(7 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT)	/* IEEE80211_VHTCAP_BEAMFORMEE_STS_MASK */
 
 #define	IEEE80211_VHT_CAP_HTC_VHT		0x00400000	/* IEEE80211_VHTCAP_HTC_VHT */
 
@@ -212,6 +233,7 @@ struct ieee80211_sta_ht_cap {
 #define	IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK	\
 	(7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT)	/* IEEE80211_VHTCAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK */
 
+
 struct ieee80211_sta_vht_cap {
 		/* TODO FIXME */
 	bool			vht_supported;
@@ -578,17 +600,6 @@ struct mac_address {
 	uint8_t	addr[ETH_ALEN];
 };
 
-#define	REG_RULE(_begin, _end, _bw, _gain, _eirp, _x)			\
-{									\
-	.freq_range.start_freq_khz = (_begin) * 1000,			\
-	.freq_range.end_freq_khz = (_end) * 1000,			\
-	.freq_range.max_bandwidth_khz = (_bw) * 1000,			\
-	.power_rule.max_antenna_gain = DBI_TO_MBI(_gain),		\
-	.power_rule.max_eirp = DBM_TO_MBM(_eirp),			\
-	.flags = (_x),				/* ? */			\
-	/* XXX TODO FIXME */						\
-}
-
 struct ieee80211_reg_rule {
 	/* TODO FIXME */
 	uint32_t	flags;
@@ -606,6 +617,7 @@ struct ieee80211_reg_rule {
 struct linuxkpi_ieee80211_regdomain {
 	/* TODO FIXME */
 	uint8_t					alpha2[2];
+	int	dfs_region;
 	int					n_reg_rules;
 	struct ieee80211_reg_rule		reg_rules[];
 };
@@ -812,6 +824,19 @@ struct cfg80211_gtk_rekey_data {
 	int     kck, kek, replay_ctr;
 };
 
+struct cfg80211_tid_cfg {
+	/* XXX TODO */
+	int	mask, noack, retry_long, rtscts, tids;
+	enum nl80211_tx_rate_setting		txrate_type;
+	struct cfg80211_bitrate_mask		txrate_mask;
+};
+
+struct cfg80211_tid_config {
+	/* XXX TODO */
+	int	n_tid_conf;
+	struct cfg80211_tid_cfg			tid_conf[0];
+};
+
 struct ieee80211_iface_limit {
 	/* TODO FIXME */
 	int		max, types;
@@ -861,6 +886,12 @@ struct wiphy_iftype_ext_capab {
 
 };
 
+struct tid_config_support {
+	/* TODO FIXME */
+	uint64_t				vif;	/* enum nl80211_tid_cfg_attr */
+	uint64_t		 		peer;	/* enum nl80211_tid_cfg_attr */
+};
+
 enum cfg80211_regulatory {
 	REGULATORY_CUSTOM_REG			= BIT(0),
 	REGULATORY_STRICT_REG			= BIT(1),
@@ -868,6 +899,7 @@ enum cfg80211_regulatory {
 	REGULATORY_ENABLE_RELAX_NO_IR		= BIT(3),
 	REGULATORY_WIPHY_SELF_MANAGED		= BIT(4),
 	REGULATORY_COUNTRY_IE_IGNORE		= BIT(5),
+	REGULATORY_COUNTRY_IE_FOLLOW_POWER	= BIT(6),
 };
 
 #define	WIPHY_FLAG_AP_UAPSD			0x00000001
@@ -883,6 +915,7 @@ enum cfg80211_regulatory {
 #define	WIPHY_FLAG_SUPPORTS_FW_ROAM		0x00000400
 #define	WIPHY_FLAG_SUPPORTS_TDLS		0x00000800
 #define	WIPHY_FLAG_TDLS_EXTERNAL_SETUP		0x00001000
+#define	WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD	0x00002000
 
 struct wiphy {
 
@@ -898,7 +931,7 @@ struct wiphy {
 	const struct cfg80211_sar_capa		*sar_capa;
 	const struct wiphy_iftype_ext_capab	*iftype_ext_capab;
 	const struct linuxkpi_ieee80211_regdomain *regd;
-	char					fw_version[64];		/* XXX TODO */
+	char					fw_version[ETHTOOL_FWVERS_LEN];
 	const struct ieee80211_iface_combination *iface_combinations;
 	const uint32_t				*cipher_suites;
 	int					n_iface_combinations;
@@ -910,6 +943,7 @@ struct wiphy {
 	const struct ieee80211_txrx_stypes	*mgmt_stypes;
 	uint32_t				rts_threshold;
 	uint32_t				frag_threshold;
+	struct tid_config_support		tid_config_support;
 
 	int	available_antennas_rx, available_antennas_tx;
 	int	features, hw_version;
@@ -917,6 +951,8 @@ struct wiphy {
 	int	num_iftype_ext_capab;
 	int	max_ap_assoc_sta, probe_resp_offload, software_iftypes;
 	int     bss_select_support, max_num_pmkids, retry_long, retry_short, signal_type;
+	int	max_data_retry_count;
+	int     tx_queue_len;
 
 	unsigned long				ext_features[BITS_TO_LONGS(NUM_NL80211_EXT_FEATURES)];
 	struct dentry				*debugfsdir;
@@ -994,6 +1030,8 @@ int linuxkpi_regulatory_set_wiphy_regd_sync(struct wiphy *wiphy,
     struct linuxkpi_ieee80211_regdomain *regd);
 uint32_t linuxkpi_ieee80211_channel_to_frequency(uint32_t, enum nl80211_band);
 uint32_t linuxkpi_ieee80211_frequency_to_channel(uint32_t, uint32_t);
+struct linuxkpi_ieee80211_channel *
+    linuxkpi_ieee80211_get_channel(struct wiphy *, uint32_t);
 
 /* -------------------------------------------------------------------------- */
 
@@ -1196,6 +1234,13 @@ regulatory_hint(struct wiphy *wiphy, const uint8_t *alpha2)
 	return (-ENXIO);
 }
 
+static __inline const char *
+reg_initiator_name(enum nl80211_reg_initiator initiator)
+{
+	TODO();
+	return (NULL);
+}
+
 static __inline struct linuxkpi_ieee80211_regdomain *
 rtnl_dereference(const struct linuxkpi_ieee80211_regdomain *regd)
 {
@@ -1236,8 +1281,10 @@ wiphy_name(struct wiphy *wiphy)
 {
 	if (wiphy != NULL && wiphy->dev != NULL)
 		return dev_name(wiphy->dev);
-	else
+	else {
+		IMPROVE("wlanNA");
 		return ("wlanNA");
+	}
 }
 
 static __inline void
@@ -1342,7 +1389,7 @@ cfg80211_ibss_joined(struct net_device *ndev, const uint8_t *addr,
 static __inline struct cfg80211_bss *
 cfg80211_inform_bss(struct wiphy *wiphy,
     struct linuxkpi_ieee80211_channel *channel,
-    enum cfg80211_bss_ftypes bss_ftype, const uint8_t *bss, int _x,
+    enum cfg80211_bss_frame_type bss_ftype, const uint8_t *bss, int _x,
     uint16_t cap, uint16_t intvl, const uint8_t *ie, size_t ie_len,
     int signal, gfp_t gfp)
 {
@@ -1353,7 +1400,7 @@ cfg80211_inform_bss(struct wiphy *wiphy,
 static __inline struct cfg80211_bss *
 cfg80211_inform_bss_data(struct wiphy *wiphy,
     struct cfg80211_inform_bss *bss_data,
-    enum cfg80211_bss_ftypes bss_ftype, const uint8_t *bss, int _x,
+    enum cfg80211_bss_frame_type bss_ftype, const uint8_t *bss, int _x,
     uint16_t cap, uint16_t intvl, const uint8_t *ie, size_t ie_len, gfp_t gfp)
 {
 	TODO();
@@ -1471,8 +1518,8 @@ cfg80211_vendor_cmd_reply(struct sk_buff *skb)
 static __inline struct linuxkpi_ieee80211_channel *
 ieee80211_get_channel(struct wiphy *wiphy, uint32_t freq)
 {
-	TODO();
-	return (NULL);
+
+	return (linuxkpi_ieee80211_get_channel(wiphy, freq));
 }
 
 static __inline size_t
@@ -1501,6 +1548,14 @@ cfg80211_channel_is_psc(struct linuxkpi_ieee80211_channel *channel)
 	return (false);
 }
 
+static __inline int
+cfg80211_get_ies_channel_number(const uint8_t *ie, size_t len,
+    enum nl80211_band band, enum cfg80211_bss_frame_type ftype)
+{
+
+	TODO();
+	return (-1);
+}
 
 /* Used for scanning at least. */
 static __inline void
diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h
index 7c3afebb19f8..d2e2f1412b7e 100644
--- a/sys/compat/linuxkpi/common/include/net/mac80211.h
+++ b/sys/compat/linuxkpi/common/include/net/mac80211.h
@@ -37,6 +37,7 @@
 #include <asm/atomic64.h>
 #include <linux/bitops.h>
 #include <linux/etherdevice.h>
+#include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/workqueue.h>
@@ -45,6 +46,7 @@
 #define	ARPHRD_IEEE80211_RADIOTAP		__LINE__ /* XXX TODO brcmfmac */
 
 #define	WLAN_OUI_MICROSOFT			(0x0050F2)
+#define	WLAN_OUI_TYPE_MICROSOFT_WPA		(1)
 #define	WLAN_OUI_TYPE_MICROSOFT_TPC		(8)
 #define	WLAN_OUI_TYPE_WFA_P2P			(9)
 #define	WLAN_OUI_WFA				(0x506F9A)
@@ -53,6 +55,7 @@
 enum ieee80211_hw_conf_flags {
 	IEEE80211_CONF_IDLE			= BIT(0),
 	IEEE80211_CONF_PS			= BIT(1),
+	IEEE80211_CONF_MONITOR			= BIT(2),
 };
 
 /* (*ops->config()) */
@@ -60,6 +63,7 @@ enum ieee80211_hw_conf_changed_flags {
 	IEEE80211_CONF_CHANGE_CHANNEL		= BIT(0),
 	IEEE80211_CONF_CHANGE_IDLE		= BIT(1),
 	IEEE80211_CONF_CHANGE_PS		= BIT(2),
+	IEEE80211_CONF_CHANGE_MONITOR		= BIT(3),
 };
 
 #define	CFG80211_TESTMODE_CMD(_x)	/* XXX TODO */
@@ -73,6 +77,8 @@ enum mcast_filter_flags {
 	FIF_BCN_PRBRESP_PROMISC		= BIT(2),
 	FIF_FCSFAIL			= BIT(3),
 	FIF_OTHER_BSS			= BIT(4),
+	FIF_PSPOLL			= BIT(5),
+	FIF_CONTROL			= BIT(6),
 };
 
 enum ieee80211_bss_changed {
@@ -96,6 +102,12 @@ enum ieee80211_bss_changed {
 	BSS_CHANGED_QOS			= BIT(17),
 	BSS_CHANGED_TXPOWER		= BIT(18),
 	BSS_CHANGED_HE_BSS_COLOR	= BIT(19),
+	BSS_CHANGED_AP_PROBE_RESP	= BIT(20),
+	BSS_CHANGED_BASIC_RATES		= BIT(21),
+	BSS_CHANGED_ERP_PREAMBLE	= BIT(22),
+	BSS_CHANGED_IBSS		= BIT(23),
+	BSS_CHANGED_MCAST_RATE		= BIT(24),
+	BSS_CHANGED_SSID		= BIT(25),
 };
 
 /* 802.11 Figure 9-256 Suite selector format. [OUI(3), SUITE TYPE(1)] */
@@ -158,10 +170,23 @@ struct ieee80211_bar {
 	uint16_t	frame_control;
 };
 
+struct ieee80211_p2p_noa_desc {
+	uint32_t				count;		/* uint8_t ? */
+	uint32_t				duration;
+	uint32_t				interval;
+	uint32_t				start_time;
+};
+
 struct ieee80211_p2p_noa_attr {
+	uint8_t					index;
+	uint8_t					oppps_ctwindow;
+	struct ieee80211_p2p_noa_desc		desc[4];
+};
+
+struct ieee80211_mutable_offsets {
 	/* TODO FIXME */
-	int		oppps_ctwindow;
-	int     desc, index;
+	uint16_t				tim_offset;
+	int     cntdwn_counter_offs;
 };
 
 #define	WLAN_MEMBERSHIP_LEN			(8)
@@ -203,13 +228,15 @@ struct ieee80211_bss_conf {
 	uint64_t				sync_tsf;
 	uint8_t					sync_dtim_count;
 	int16_t					txpower;
+	int					mcast_rate[NUM_NL80211_BANDS];
 
 	int		ack_enabled, bssid_index, bssid_indicator, cqm_rssi_hyst, cqm_rssi_thold, ema_ap, frame_time_rts_th, ftm_responder;
 	int		htc_trig_based_pkt_ext;
 	int		multi_sta_back_32bit, nontransmitted;
 	int		profile_periodicity;
 	int		twt_requester, uora_exists, uora_ocw_range;
-	int		assoc_capability, enable_beacon, hidden_ssid, ibss_joined, mcast_rate, twt_protected;
+	int		assoc_capability, enable_beacon, hidden_ssid, ibss_joined, twt_protected;
+	int		fils_discovery, he_obss_pd, he_oper, twt_responder, unsol_bcast_probe_resp_interval;
 	unsigned long	basic_rates;
 	bool		he_support;
 };
@@ -299,6 +326,13 @@ struct ieee80211_he_mu_edca_param_ac_rec {
 	int		aifsn, ecw_min_max, mu_edca_timer;
 };
 
+struct ieee80211_conf {
+	int					dynamic_ps_timeout;
+	uint32_t				listen_interval;
+	enum ieee80211_hw_conf_flags		flags;
+	struct cfg80211_chan_def		chandef;
+};
+
 enum ieee80211_hw_flags {
 	IEEE80211_HW_AMPDU_AGGREGATION,
 	IEEE80211_HW_AP_LINK_PS,
@@ -331,6 +365,12 @@ enum ieee80211_hw_flags {
 	IEEE80211_HW_TX_FRAG_LIST,
 	IEEE80211_HW_USES_RSS,
 	IEEE80211_HW_WANT_MONITOR_VIF,
+	IEEE80211_HW_SW_CRYPTO_CONTROL,
+	IEEE80211_HW_SUPPORTS_TX_FRAG,
+	IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA,
+	IEEE80211_HW_SUPPORTS_PER_STA_GTK,
+	IEEE80211_HW_REPORTS_LOW_ACK,
+	IEEE80211_HW_QUEUE_CONTROL,
 
 	/* Keep last. */
 	NUM_IEEE80211_HW_FLAGS
@@ -365,11 +405,7 @@ struct ieee80211_hw {
 	uint16_t			max_listen_interval;
 	netdev_features_t		netdev_features;
 	unsigned long			flags[BITS_TO_LONGS(NUM_IEEE80211_HW_FLAGS)];
-	struct {
-		uint32_t			listen_interval;
-		enum ieee80211_hw_conf_flags	flags;
-		struct cfg80211_chan_def	chandef;
-	} conf;
+	struct ieee80211_conf		conf;
 
 #if 0	/* leave here for documentation purposes.  This does NOT work. */
 	/* Must stay last. */
@@ -386,6 +422,7 @@ enum ieee802111_key_flag {
 	IEEE80211_KEY_FLAG_PUT_IV_SPACE		= BIT(3),
 	IEEE80211_KEY_FLAG_PUT_MIC_SPACE	= BIT(4),
 	IEEE80211_KEY_FLAG_SW_MGMT_TX		= BIT(5),
+	IEEE80211_KEY_FLAG_GENERATE_IV_MGMT	= BIT(6),
 };
 
 struct ieee80211_key_conf {
@@ -421,10 +458,6 @@ struct ieee80211_key_seq {
 };
 
 
-struct ieee80211_p2p_noa_desc {
-	/* TODO FIXME */
-};
-
 enum ieee80211_rx_status_flags {
 	RX_FLAG_ALLOW_SAME_PN		= BIT(0),
 	RX_FLAG_AMPDU_DETAILS		= BIT(1),
@@ -446,6 +479,13 @@ enum ieee80211_rx_status_flags {
 	RX_FLAG_RADIOTAP_LSIG		= BIT(17),
 	RX_FLAG_RADIOTAP_VENDOR_DATA	= BIT(18),
 	RX_FLAG_NO_SIGNAL_VAL		= BIT(19),
+	RX_FLAG_IV_STRIPPED		= BIT(20),
+	RX_FLAG_AMPDU_IS_LAST		= BIT(21),
+	RX_FLAG_AMPDU_LAST_KNOWN	= BIT(22),
+	RX_FLAG_AMSDU_MORE		= BIT(23),
+	RX_FLAG_MACTIME_END		= BIT(24),
+	RX_FLAG_ONLY_MONITOR		= BIT(25),
+	RX_FLAG_SKIP_MONITOR		= BIT(26),
 };
 
 struct ieee80211_rx_status {
@@ -512,11 +552,17 @@ struct ieee80211_sta_rates {
 	} rate[1];		/* XXX what is the real number? */
 };
 
+struct ieee80211_sta_txpwr {
+	/* XXX TODO */
+	enum nl80211_tx_power_setting	type;
+	short				power;
+};
+
 #define	IEEE80211_NUM_TIDS			16	/* net80211::WME_NUM_TID */
 struct ieee80211_sta {
 	/* TODO FIXME */
 	int		max_amsdu_len, max_amsdu_subframes, max_rc_amsdu_len, max_sp;
-	int		mfp, rx_nss, smps_mode, tdls, tdls_initiator, uapsd_queues, wme, txpwr;
+	int		mfp, rx_nss, smps_mode, tdls, tdls_initiator, uapsd_queues, wme;
 	enum ieee80211_sta_rx_bw		bandwidth;
 	struct ieee80211_sta_ht_cap		ht_cap;
 	struct ieee80211_sta_vht_cap		vht_cap;
@@ -524,6 +570,7 @@ struct ieee80211_sta {
 	struct ieee80211_sta_he_6ghz_capa	he_6ghz_capa;
 	struct ieee80211_txq			*txq[IEEE80211_NUM_TIDS + 1];	/* iwlwifi: 8 and adds +1 to tid_data, net80211::IEEE80211_TID_SIZE */
 	struct ieee80211_sta_rates		*rates;	/* some rcu thing? */
+	struct ieee80211_sta_txpwr		txpwr;
 	uint32_t				max_tid_amsdu_len[IEEE80211_NUM_TIDS];
 	uint32_t				supp_rates[NUM_NL80211_BANDS];
 	uint8_t					addr[ETH_ALEN];
@@ -574,7 +621,8 @@ struct ieee80211_vif {
 	/* TODO FIXME */
 	enum nl80211_iftype		type;
 	int		csa_active, mu_mimo_owner;
-	int		cab_queue, hw_queue;
+	int		cab_queue;
+	int     color_change_active, offload_flags;
 	enum ieee80211_vif_driver_flags	driver_flags;
 	bool				p2p;
 	bool				probe_req_reg;
@@ -582,6 +630,7 @@ struct ieee80211_vif {
 	struct ieee80211_chanctx_conf	*chanctx_conf;
 	struct ieee80211_txq		*txq;
 	struct ieee80211_bss_conf	bss_conf;
+	uint8_t				hw_queue[IEEE80211_NUM_ACS];
 
 	/* Must stay last. */
 	uint8_t				drv_priv[0] __aligned(CACHE_LINE_SIZE);
@@ -623,20 +672,19 @@ struct ieee80211_tx_info {
 			bool				is_valid_ack_signal;
 			void				*status_driver_data[2];		/* XXX TODO */
 		} status;
-		void					*driver_data[5];		/* XXX TODO */
+#define	IEEE80211_TX_INFO_DRIVER_DATA_SIZE	(5 * sizeof(void *))			/* XXX TODO 5? */
+		void					*driver_data[IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)];
 	};
 };
 
 /* net80211 conflict */
-#ifdef FIXME_TODO
-struct ieee80211_tim_ie {
-	/* TODO FIXME */
+struct linuxkpi_ieee80211_tim_ie {
 	uint8_t				dtim_count;
 	uint8_t				dtim_period;
 	uint8_t				bitmap_ctrl;
-	uint8_t				virtual_map;
+	uint8_t				*virtual_map;
 };
-#endif
+#define	ieee80211_tim_ie	linuxkpi_ieee80211_tim_ie
 
 struct survey_info {		/* net80211::struct ieee80211_channel_survey */
 	/* TODO FIXME */
@@ -662,6 +710,7 @@ struct survey_info {		/* net80211::struct ieee80211_channel_survey */
 enum ieee80211_iface_iter {
 	IEEE80211_IFACE_ITER_NORMAL	= BIT(0),
 	IEEE80211_IFACE_ITER_RESUME_ALL	= BIT(1),
+	IEEE80211_IFACE_SKIP_SDATA_NOT_IN_DRIVER = BIT(2),	/* seems to be an iter flag */
 
 	/* Internal flags only. */
 	/* ieee80211_iterate_active_interfaces*(). */
@@ -734,6 +783,7 @@ struct ieee80211_ops {
 	void (*sta_notify)(struct ieee80211_hw *, struct ieee80211_vif *, enum sta_notify_cmd, struct ieee80211_sta *);
 	void (*sta_rc_update)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, u32);
 	void (*sta_rate_tbl_update)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *);
+	void (*sta_set_4addr)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, bool);
 
 	u64  (*prepare_multicast)(struct ieee80211_hw *, struct netdev_hw_addr_list *);
 
@@ -790,7 +840,14 @@ struct ieee80211_ops {
 
 	int (*set_sar_specs)(struct ieee80211_hw *, const struct cfg80211_sar_specs *);
 
-	/* XXX TODO: get_et_sset_count, get_et_stats, get_et_strings */
+	int (*set_tid_config)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, struct cfg80211_tid_config *);
+	int (*reset_tid_config)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, u8);
+
+	int (*get_et_sset_count)(struct ieee80211_hw *, struct ieee80211_vif *, int);
+	void (*get_et_stats)(struct ieee80211_hw *, struct ieee80211_vif *, struct ethtool_stats *, u64 *);
+	void (*get_et_strings)(struct ieee80211_hw *, struct ieee80211_vif *, u32, u8 *);
+
+	void (*update_vif_offload)(struct ieee80211_hw *, struct ieee80211_vif *);
 };
 
 
@@ -803,7 +860,7 @@ struct ieee80211_hw *linuxkpi_ieee80211_alloc_hw(size_t,
     const struct ieee80211_ops *);
 void linuxkpi_ieee80211_iffree(struct ieee80211_hw *);
 void linuxkpi_set_ieee80211_dev(struct ieee80211_hw *, char *);
-void linuxkpi_ieee80211_ifattach(struct ieee80211_hw *);
+int linuxkpi_ieee80211_ifattach(struct ieee80211_hw *);
 void linuxkpi_ieee80211_ifdetach(struct ieee80211_hw *);
 struct ieee80211_hw * linuxkpi_wiphy_to_ieee80211_hw(struct wiphy *);
 void linuxkpi_ieee80211_iterate_interfaces(
@@ -829,7 +886,7 @@ uint8_t linuxkpi_ieee80211_get_tid(struct ieee80211_hdr *);
 struct ieee80211_sta *linuxkpi_ieee80211_find_sta(struct ieee80211_vif *,
     const u8 *);
 struct ieee80211_sta *linuxkpi_ieee80211_find_sta_by_ifaddr(
-    struct ieee80211_hw *, uint8_t *, uint8_t *);
+    struct ieee80211_hw *, const uint8_t *, const uint8_t *);
 struct sk_buff *linuxkpi_ieee80211_tx_dequeue(struct ieee80211_hw *,
     struct ieee80211_txq *);
 bool linuxkpi_ieee80211_is_ie_id_in_ie_buf(const u8, const u8 *, size_t);
@@ -924,11 +981,11 @@ ieee80211_register_hw(struct ieee80211_hw *hw)
 	 * setup is done.
 	 * We need to replicate a lot of information from here into net80211.
 	 */
-	linuxkpi_ieee80211_ifattach(hw);
+	error = linuxkpi_ieee80211_ifattach(hw);
 
 	IMPROVE();
 
-	return (0);
+	return (error);
 }
 
 static __inline void
@@ -1337,7 +1394,7 @@ ieee80211_vif_to_wdev(struct ieee80211_vif *vif)
 
 static __inline struct sk_buff *
 ieee80211_beacon_get_template(struct ieee80211_hw *hw,
-    struct ieee80211_vif *vif, void *p /* XXX TODO */)
+    struct ieee80211_vif *vif, struct ieee80211_mutable_offsets *offs)
 {
 	TODO();
 	return (NULL);
@@ -1431,8 +1488,8 @@ ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *peer)
 }
 
 static __inline struct ieee80211_sta *
-ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, uint8_t *addr,
-    uint8_t *ourvifaddr)
+ieee80211_find_sta_by_ifaddr(struct ieee80211_hw *hw, const uint8_t *addr,
+    const uint8_t *ourvifaddr)
 {
 
 	return (linuxkpi_ieee80211_find_sta_by_ifaddr(hw, addr, ourvifaddr));
diff --git a/sys/compat/linuxkpi/common/include/net/regulatory.h b/sys/compat/linuxkpi/common/include/net/regulatory.h
new file mode 100644
index 000000000000..a7b31812e308
--- /dev/null
+++ b/sys/compat/linuxkpi/common/include/net/regulatory.h
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2020-2021 The FreeBSD Foundation
+ * Copyright (c) 2021-2022 Bjoern A. Zeeb
+ *
+ * This software was developed by Björn Zeeb under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef	_LINUXKPI_NET_REGULATORY_H
+#define	_LINUXKPI_NET_REGULATORY_H
+
+#define	REG_RULE(_begin, _end, _bw, _mag, _meirp, _flags)		\
+{									\
+	.flags = (_flags),						\
+	.freq_range.start_freq_khz = MHZ_TO_KHZ(_begin),		\
*** 78 LINES SKIPPED ***