diff --git a/sys/compat/linuxkpi/common/include/linux/ieee80211.h b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
index aa1a0a4f3c5f..9a43a571d390 100644
--- a/sys/compat/linuxkpi/common/include/linux/ieee80211.h
+++ b/sys/compat/linuxkpi/common/include/linux/ieee80211.h
@@ -1,803 +1,856 @@
 /*-
- * Copyright (c) 2020-2023 The FreeBSD Foundation
+ * Copyright (c) 2020-2024 The FreeBSD Foundation
  *
  * 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.
  */
 
 #ifndef	_LINUXKPI_LINUX_IEEE80211_H
 #define	_LINUXKPI_LINUX_IEEE80211_H
 
 #include <sys/types.h>
 #include <net80211/ieee80211.h>
 
 #include <asm/unaligned.h>
+#include <linux/kernel.h>
 #include <linux/bitops.h>
 #include <linux/if_ether.h>
 
 
 /* 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
 
 #define	IEEE80211_MAX_PN_LEN			16
 
 #define	IEEE80211_INVAL_HW_QUEUE		((uint8_t)-1)
 
 #define	IEEE80211_MAX_AMPDU_BUF_HT		IEEE80211_AGGR_BAWMAX
 #define	IEEE80211_MAX_AMPDU_BUF_HE		256
 #define	IEEE80211_MAX_AMPDU_BUF_EHT		1024
 
 #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 */
 #define	IEEE80211_MAX_MPDU_LEN_HT_3839		3839
 #define	IEEE80211_MAX_MPDU_LEN_HT_7935		7935
 #define	IEEE80211_MAX_MPDU_LEN_VHT_3895		3895
 #define	IEEE80211_MAX_MPDU_LEN_VHT_7991		7991
 #define	IEEE80211_MAX_MPDU_LEN_VHT_11454	11454
 
 #define	IEEE80211_MAX_RTS_THRESHOLD		2346	/* net80211::IEEE80211_RTS_MAX */
 
 #define	IEEE80211_MIN_ACTION_SIZE		23	/* ? */
 
 /* Wi-Fi Peer-to-Peer (P2P) Technical Specification */
 #define	IEEE80211_P2P_OPPPS_CTWINDOW_MASK	0x7f
 #define	IEEE80211_P2P_OPPPS_ENABLE_BIT		BIT(7)
 
 /* 802.11-2016, 9.2.4.5.1, Table 9-6 QoS Control Field */
 #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
 #define	IEEE80211_QOS_CTL_ACK_POLICY_MASK	0x0060
 #define	IEEE80211_QOS_CTL_ACK_POLICY_NOACK	0x0020
 #define	IEEE80211_QOS_CTL_MESH_CONTROL_PRESENT	0x0100
 
 #define	IEEE80211_RATE_SHORT_PREAMBLE		BIT(0)
 
 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
 #define	IEEE80211_SCTL_SEQ			IEEE80211_SEQ_SEQ_MASK
 
 #define	IEEE80211_TKIP_ICV_LEN			4
 #define	IEEE80211_TKIP_IV_LEN			8	/* WEP + KID + EXT */
 
 #define	IEEE80211_VHT_EXT_NSS_BW_CAPABLE	(1 << 13)	/* assigned to tx_highest */
 
 #define	IEEE80211_VHT_MAX_AMPDU_1024K		7	/* 9.4.2.56.3 A-MPDU Parameters field, Table 9-163 */
 
 #define	IEEE80211_WEP_IV_LEN			3	/* net80211: IEEE80211_WEP_IVLEN */
 #define	IEEE80211_WEP_ICV_LEN			4
 
 #define	WLAN_AUTH_OPEN				__LINE__ /* TODO FIXME brcmfmac */
 #define	WLAN_CAPABILITY_IBSS			__LINE__ /* TODO FIXME no longer used? */
 #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_MAX_KEY_LEN			32
+#define	WLAN_PMKID_LEN				16
+#define	WLAN_PMK_LEN_SUITE_B_192		48
 
 #define	WLAN_KEY_LEN_WEP40			5
 #define	WLAN_KEY_LEN_WEP104			13
 #define	WLAN_KEY_LEN_TKIP			32
 #define	WLAN_KEY_LEN_CCMP			16
 #define	WLAN_KEY_LEN_GCMP			16
 #define	WLAN_KEY_LEN_AES_CMAC			16
 #define	WLAN_KEY_LEN_GCMP_256			32
 #define	WLAN_KEY_LEN_BIP_CMAC_256		32
 #define	WLAN_KEY_LEN_BIP_GMAC_128		16
 #define	WLAN_KEY_LEN_BIP_GMAC_256		32
 
 /* 802.11-2020, 9.4.2.55.3, Table 9-185 Subfields of the A-MPDU Parameters field */
 enum ieee80211_min_mpdu_start_spacing {
 	IEEE80211_HT_MPDU_DENSITY_NONE		= 0,
 #if 0
 	IEEE80211_HT_MPDU_DENSITY_XXX		= 1,	/* 1/4 us */
 #endif
 	IEEE80211_HT_MPDU_DENSITY_0_5		= 2,	/* 1/2 us */
 	IEEE80211_HT_MPDU_DENSITY_1		= 3,	/* 1 us */
 	IEEE80211_HT_MPDU_DENSITY_2		= 4,	/* 2 us */
 	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_FCTL_FROMDS			(IEEE80211_FC1_DIR_FROMDS << 8)
 #define	IEEE80211_FCTL_TODS			(IEEE80211_FC1_DIR_TODS << 8)
 #define	IEEE80211_FCTL_MOREFRAGS		(IEEE80211_FC1_MORE_FRAG << 8)
 #define	IEEE80211_FCTL_PM			(IEEE80211_FC1_PWR_MGT << 8)
 
 #define	IEEE80211_FTYPE_MGMT			IEEE80211_FC0_TYPE_MGT
 #define	IEEE80211_FTYPE_CTL			IEEE80211_FC0_TYPE_CTL
 #define	IEEE80211_FTYPE_DATA			IEEE80211_FC0_TYPE_DATA
 
 #define	IEEE80211_STYPE_ASSOC_REQ		IEEE80211_FC0_SUBTYPE_ASSOC_REQ
 #define	IEEE80211_STYPE_REASSOC_REQ		IEEE80211_FC0_SUBTYPE_REASSOC_REQ
 #define	IEEE80211_STYPE_PROBE_REQ		IEEE80211_FC0_SUBTYPE_PROBE_REQ
 #define	IEEE80211_STYPE_DISASSOC		IEEE80211_FC0_SUBTYPE_DISASSOC
 #define	IEEE80211_STYPE_AUTH			IEEE80211_FC0_SUBTYPE_AUTH
 #define	IEEE80211_STYPE_DEAUTH			IEEE80211_FC0_SUBTYPE_DEAUTH
 #define	IEEE80211_STYPE_CTS			IEEE80211_FC0_SUBTYPE_CTS
 #define	IEEE80211_STYPE_RTS			IEEE80211_FC0_SUBTYPE_RTS
 #define	IEEE80211_STYPE_ACTION			IEEE80211_FC0_SUBTYPE_ACTION
+#define	IEEE80211_STYPE_DATA			IEEE80211_FC0_SUBTYPE_DATA
 #define	IEEE80211_STYPE_QOS_DATA		IEEE80211_FC0_SUBTYPE_QOS_DATA
 #define	IEEE80211_STYPE_QOS_NULLFUNC		IEEE80211_FC0_SUBTYPE_QOS_NULL
 #define	IEEE80211_STYPE_QOS_CFACK		0xd0	/* XXX-BZ reserved? */
 
 #define	IEEE80211_NUM_ACS			4	/* net8021::WME_NUM_AC */
 
 #define	IEEE80211_MAX_SSID_LEN			32	/* 9.4.2.2 SSID element, net80211: IEEE80211_NWID_LEN */
 
 
 /* Figure 9-27, BAR Control field */
 #define	IEEE80211_BAR_CTRL_TID_INFO_MASK	0xf000
 #define	IEEE80211_BAR_CTRL_TID_INFO_SHIFT	12
 
 #define	IEEE80211_PPE_THRES_INFO_PPET_SIZE		1 /* TODO FIXME ax? */
 #define	IEEE80211_PPE_THRES_NSS_MASK			2 /* TODO FIXME ax? */
 #define	IEEE80211_PPE_THRES_RU_INDEX_BITMASK_POS	3 /* TODO FIXME ax? */
 #define	IEEE80211_PPE_THRES_RU_INDEX_BITMASK_MASK	8 /* TODO FIXME ax? */
 #define	IEEE80211_HE_PPE_THRES_INFO_HEADER_SIZE		16	/* TODO FIXME ax? */
 
 /* 802.11-2012, Table 8-130-HT Operation element fields and subfields, HT Protection */
 #define	IEEE80211_HT_OP_MODE_PROTECTION			IEEE80211_HTINFO_OPMODE		/* Mask. */
 #define	IEEE80211_HT_OP_MODE_PROTECTION_NONE		IEEE80211_HTINFO_OPMODE_PURE	/* No protection */
 #define	IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER	IEEE80211_HTINFO_OPMODE_PROTOPT	/* Nonmember protection */
 #define	IEEE80211_HT_OP_MODE_PROTECTION_20MHZ		IEEE80211_HTINFO_OPMODE_HT20PR	/* 20 MHz protection */
 #define	IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED	IEEE80211_HTINFO_OPMODE_MIXED	/* Non-HT mixed */
 
 
 /* 9.6.13.1, Table 9-342 TDLS Action field values. */
 enum ieee80211_tdls_action_code {
 	WLAN_TDLS_SETUP_REQUEST			= 0,
 	WLAN_TDLS_SETUP_RESPONSE		= 1,
 	WLAN_TDLS_SETUP_CONFIRM			= 2,
 	WLAN_TDLS_TEARDOWN			= 3,
 	WLAN_TDLS_PEER_TRAFFIC_INDICATION	= 4,
 	WLAN_TDLS_CHANNEL_SWITCH_REQUEST	= 5,
 	WLAN_TDLS_CHANNEL_SWITCH_RESPONSE	= 6,
 	WLAN_TDLS_PEER_PSM_REQUEST		= 7,
 	WLAN_TDLS_PEER_PSM_RESPONSE		= 8,
 	WLAN_TDLS_PEER_TRAFFIC_RESPONSE		= 9,
 	WLAN_TDLS_DISCOVERY_REQUEST		= 10,
 	/* 11-255 reserved */
 };
 
 /* 802.11-2020 9.4.2.26, Table 9-153. Extended Capabilities field. */
 /* This is split up into octets CAPA1 = octet 1, ... */
 #define	WLAN_EXT_CAPA1_EXT_CHANNEL_SWITCHING			BIT(2  % 8)
 #define	WLAN_EXT_CAPA3_MULTI_BSSID_SUPPORT			BIT(22 % 8)
 #define	WLAN_EXT_CAPA3_TIMING_MEASUREMENT_SUPPORT		BIT(23 % 8)
 #define	WLAN_EXT_CAPA8_OPMODE_NOTIF				BIT(62 % 8)
 #define	WLAN_EXT_CAPA8_MAX_MSDU_IN_AMSDU_LSB			BIT(63 % 8)
 #define	WLAN_EXT_CAPA9_MAX_MSDU_IN_AMSDU_MSB			BIT(64 % 8)
 #define	WLAN_EXT_CAPA10_TWT_REQUESTER_SUPPORT			BIT(77 % 8)
 #define	WLAN_EXT_CAPA10_TWT_RESPONDER_SUPPORT			BIT(78 % 8)
 #define	WLAN_EXT_CAPA10_OBSS_NARROW_BW_RU_TOLERANCE_SUPPORT	BIT(79 % 8)
 
 #define	WLAN_EXT_CAPA11_EMA_SUPPORT				0x00	/* XXX TODO FIXME */
 
 
 /* iwlwifi/mvm/utils:: for (ac = IEEE80211_AC_VO; ac <= IEEE80211_AC_VI; ac++) */
 /* Would be so much easier if we'd define constants to the same. */
 enum ieee80211_ac_numbers {
 	IEEE80211_AC_VO = 0,			/* net80211::WME_AC_VO */
 	IEEE80211_AC_VI = 1,			/* net80211::WME_AC_VI */
 	IEEE80211_AC_BE = 2,			/* net80211::WME_AC_BE */
 	IEEE80211_AC_BK = 3,			/* net80211::WME_AC_BK */
 };
 
 #define	IEEE80211_MAX_QUEUES			16	/* Assume IEEE80211_NUM_TIDS for the moment. */
 
 #define	IEEE80211_WMM_IE_STA_QOSINFO_AC_VO	1
 #define	IEEE80211_WMM_IE_STA_QOSINFO_AC_VI	2
 #define	IEEE80211_WMM_IE_STA_QOSINFO_AC_BK	4
 #define	IEEE80211_WMM_IE_STA_QOSINFO_AC_BE	8
 #define	IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL	0xf
 
 
 /* Define the LinuxKPI names directly to the net80211 ones. */
 #define	IEEE80211_HT_CAP_LDPC_CODING		IEEE80211_HTCAP_LDPC
 #define	IEEE80211_HT_CAP_SUP_WIDTH_20_40	IEEE80211_HTCAP_CHWIDTH40
 #define	IEEE80211_HT_CAP_SM_PS			IEEE80211_HTCAP_SMPS
 #define	IEEE80211_HT_CAP_SM_PS_SHIFT		2
 #define	IEEE80211_HT_CAP_GRN_FLD		IEEE80211_HTCAP_GREENFIELD
 #define	IEEE80211_HT_CAP_SGI_20			IEEE80211_HTCAP_SHORTGI20
 #define	IEEE80211_HT_CAP_SGI_40			IEEE80211_HTCAP_SHORTGI40
 #define	IEEE80211_HT_CAP_TX_STBC		IEEE80211_HTCAP_TXSTBC
 #define	IEEE80211_HT_CAP_RX_STBC		IEEE80211_HTCAP_RXSTBC
 #define	IEEE80211_HT_CAP_RX_STBC_SHIFT		IEEE80211_HTCAP_RXSTBC_S
 #define	IEEE80211_HT_CAP_MAX_AMSDU		IEEE80211_HTCAP_MAXAMSDU
 #define	IEEE80211_HT_CAP_DSSSCCK40		IEEE80211_HTCAP_DSSSCCK40
 #define	IEEE80211_HT_CAP_LSIG_TXOP_PROT		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_TX_MAX_STREAMS_MASK	0x0c
 #define	IEEE80211_HT_MCS_RX_HIGHEST_MASK	0x3ff
 #define	IEEE80211_HT_MCS_MASK_LEN		10
 
 #define	IEEE80211_MLD_MAX_NUM_LINKS		15
+#define	IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP		0x0060
+#define	IEEE80211_MLD_CAP_OP_TID_TO_LINK_MAP_NEG_SUPP_SAME	1
 
 struct ieee80211_mcs_info {
 	uint8_t		rx_mask[IEEE80211_HT_MCS_MASK_LEN];
 	uint16_t	rx_highest;
 	uint8_t		tx_params;
 	uint8_t		__reserved[3];
 };
 
 /* 802.11-2020, 9.4.2.55.1 HT Capabilities element structure */
 struct ieee80211_ht_cap {
 	uint16_t				cap_info;
 	uint8_t					ampdu_params_info;
 	struct ieee80211_mcs_info		mcs;
 	uint16_t				extended_ht_cap_info;
 	uint32_t				tx_BF_cap_info;
 	uint8_t					antenna_selection_info;
 };
 
 #define	IEEE80211_HT_MAX_AMPDU_FACTOR		13
 #define	IEEE80211_HE_HT_MAX_AMPDU_FACTOR	16
 #define	IEEE80211_HE_VHT_MAX_AMPDU_FACTOR	20
 #define	IEEE80211_HE_6GHZ_MAX_AMPDU_FACTOR	13
 
 enum ieee80211_ht_max_ampdu_len {
 	IEEE80211_HT_MAX_AMPDU_64K
 };
 
 enum ieee80211_ampdu_mlme_action {
 	IEEE80211_AMPDU_RX_START,
 	IEEE80211_AMPDU_RX_STOP,
 	IEEE80211_AMPDU_TX_OPERATIONAL,
 	IEEE80211_AMPDU_TX_START,
 	IEEE80211_AMPDU_TX_STOP_CONT,
 	IEEE80211_AMPDU_TX_STOP_FLUSH,
 	IEEE80211_AMPDU_TX_STOP_FLUSH_CONT
 };
 
 #define	IEEE80211_AMPDU_TX_START_IMMEDIATE	1
 #define	IEEE80211_AMPDU_TX_START_DELAY_ADDBA	2
 
 enum ieee80211_chanctx_switch_mode {
 	CHANCTX_SWMODE_REASSIGN_VIF,
 	CHANCTX_SWMODE_SWAP_CONTEXTS,
 };
 
 enum ieee80211_chanctx_change_flags {
 	IEEE80211_CHANCTX_CHANGE_MIN_WIDTH	= BIT(0),
 	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),
+	IEEE80211_CHANCTX_CHANGE_PUNCTURING	= BIT(5),
 };
 
 enum ieee80211_frame_release_type {
 	IEEE80211_FRAME_RELEASE_PSPOLL		= 1,
 	IEEE80211_FRAME_RELEASE_UAPSD		= 2,
 };
 
 enum ieee80211_p2p_attr_ids {
 	IEEE80211_P2P_ATTR_DEVICE_ID,
 	IEEE80211_P2P_ATTR_DEVICE_INFO,
 	IEEE80211_P2P_ATTR_GROUP_ID,
 	IEEE80211_P2P_ATTR_LISTEN_CHANNEL,
 	IEEE80211_P2P_ATTR_ABSENCE_NOTICE,
 };
 
 enum ieee80211_reconfig_type {
 	IEEE80211_RECONFIG_TYPE_RESTART,
 	IEEE80211_RECONFIG_TYPE_SUSPEND,
 };
 
 enum ieee80211_roc_type {
 	IEEE80211_ROC_TYPE_MGMT_TX,
 	IEEE80211_ROC_TYPE_NORMAL,
 };
 
 enum ieee80211_smps_mode {
 	IEEE80211_SMPS_OFF,
 	IEEE80211_SMPS_STATIC,
 	IEEE80211_SMPS_DYNAMIC,
 	IEEE80211_SMPS_AUTOMATIC,
 	IEEE80211_SMPS_NUM_MODES,
 };
 
 /* net80211::IEEE80211_S_* different but represents the state machine. */
 /* Note: order here is important! */
 enum ieee80211_sta_state {
 	IEEE80211_STA_NOTEXIST		= 0,
 	IEEE80211_STA_NONE		= 1,
 	IEEE80211_STA_AUTH		= 2,
 	IEEE80211_STA_ASSOC		= 3,
 	IEEE80211_STA_AUTHORIZED	= 4,	/* 802.1x */
 };
 
 enum ieee80211_sta_rx_bw {
 	IEEE80211_STA_RX_BW_20,
 	IEEE80211_STA_RX_BW_40,
 	IEEE80211_STA_RX_BW_80,
 	IEEE80211_STA_RX_BW_160,
 	IEEE80211_STA_RX_BW_320,
 };
 
 enum ieee80211_tx_info_flags {
 	/* XXX TODO .. right shift numbers - not sure where that came from? */
 	IEEE80211_TX_CTL_AMPDU			= BIT(0),
 	IEEE80211_TX_CTL_ASSIGN_SEQ		= BIT(1),
 	IEEE80211_TX_CTL_NO_ACK			= BIT(2),
 	IEEE80211_TX_CTL_SEND_AFTER_DTIM	= BIT(3),
 	IEEE80211_TX_CTL_TX_OFFCHAN		= BIT(4),
 	IEEE80211_TX_CTL_REQ_TX_STATUS		= BIT(5),
 	IEEE80211_TX_STATUS_EOSP		= BIT(6),
 	IEEE80211_TX_STAT_ACK			= BIT(7),
 	IEEE80211_TX_STAT_AMPDU			= BIT(8),
 	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),
 	IEEE80211_TX_CTL_HW_80211_ENCAP		= BIT(16),
 	IEEE80211_TX_CTL_USE_MINRATE		= BIT(17),
 	IEEE80211_TX_CTL_RATE_CTRL_PROBE	= BIT(18),
 	IEEE80211_TX_CTL_LDPC			= BIT(19),
 	IEEE80211_TX_CTL_STBC			= BIT(20),
 };
 
 enum ieee80211_tx_status_flags {
 	IEEE80211_TX_STATUS_ACK_SIGNAL_VALID	= BIT(0),
 };
 
 enum ieee80211_tx_control_flags {
 	/* XXX TODO .. right shift numbers */
 	IEEE80211_TX_CTRL_PORT_CTRL_PROTO	= BIT(0),
 	IEEE80211_TX_CTRL_PS_RESPONSE		= BIT(1),
 	IEEE80211_TX_CTRL_RATE_INJECT		= BIT(2),
 	IEEE80211_TX_CTRL_MLO_LINK		= 0xF0000000,	/* This is IEEE80211_LINK_UNSPECIFIED on the high bits. */
 };
 
 enum ieee80211_tx_rate_flags {
 	/* XXX TODO .. right shift numbers */
 	IEEE80211_TX_RC_40_MHZ_WIDTH		= BIT(0),
 	IEEE80211_TX_RC_80_MHZ_WIDTH		= BIT(1),
 	IEEE80211_TX_RC_160_MHZ_WIDTH		= BIT(2),
 	IEEE80211_TX_RC_GREEN_FIELD		= BIT(3),
 	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_RNR_TBTT_PARAMS_PSD_RESERVED	-128
 
 #define	IEEE80211_HT_CTL_LEN	4
 
 struct ieee80211_hdr {		/* net80211::ieee80211_frame_addr4 */
         __le16		frame_control;
         __le16		duration_id;
 	uint8_t		addr1[ETH_ALEN];
 	uint8_t		addr2[ETH_ALEN];
 	uint8_t		addr3[ETH_ALEN];
 	__le16		seq_ctrl;
 	uint8_t		addr4[ETH_ALEN];
 };
 
 struct ieee80211_hdr_3addr {	/* net80211::ieee80211_frame */
         __le16		frame_control;
         __le16		duration_id;
 	uint8_t		addr1[ETH_ALEN];
 	uint8_t		addr2[ETH_ALEN];
 	uint8_t		addr3[ETH_ALEN];
 	__le16		seq_ctrl;
 };
 
 struct ieee80211_qos_hdr {	/* net80211:ieee80211_qosframe */
         __le16		frame_control;
         __le16		duration_id;
 	uint8_t		addr1[ETH_ALEN];
 	uint8_t		addr2[ETH_ALEN];
 	uint8_t		addr3[ETH_ALEN];
 	__le16		seq_ctrl;
 	__le16		qos_ctrl;
 };
 
 struct ieee80211_vendor_ie {
 };
 
 /* 802.11-2020, Table 9-359-Block Ack Action field values */
 enum ieee80211_back {
 	WLAN_ACTION_ADDBA_REQ		= 0,
 };
 
 /* 802.11-2020, Table 9-51-Category values */
 enum ieee80211_category {
 	WLAN_CATEGORY_BACK		= 3,
 };
 
 /* 80211-2020 9.3.3.2 Format of Management frames */
 struct ieee80211_mgmt {
 	__le16		frame_control;
         __le16		duration_id;
 	uint8_t		da[ETH_ALEN];
 	uint8_t		sa[ETH_ALEN];
 	uint8_t		bssid[ETH_ALEN];
 	__le16		seq_ctrl;
 	union {
 		/* 9.3.3.3 Beacon frame format */
 		struct {
 			uint64_t	timestamp;
 			uint16_t	beacon_int;
 			uint16_t	capab_info;
 			uint8_t		variable[0];
 		} beacon;
 		/* 9.3.3.10 Probe Request frame format */
 		struct {
 			uint8_t		variable[0];
 		} probe_req;
 		/* 9.3.3.11 Probe Response frame format */
 		struct {
 			uint64_t	timestamp;
 			uint16_t	beacon_int;
 			uint16_t	capab_info;
 			uint8_t		variable[0];
 		} probe_resp;
 		/* 9.3.3.14 Action frame format */
 		struct {
 			/* 9.4.1.11 Action field */
 			uint8_t		category;
 			/* 9.6.8 Public Action details */
 			union {
 				/* 9.6.2.5 TPC Report frame format */
 				struct {
 					uint8_t spec_mgmt;
 					uint8_t dialog_token;
 					/* uint32_t tpc_rep_elem:: */
 					uint8_t tpc_elem_id;
 					uint8_t tpc_elem_length;
 					uint8_t tpc_elem_tx_power;
 					uint8_t tpc_elem_link_margin;
 				} tpc_report;
 				/* 9.6.8.33 Fine Timing Measurement frame format */
 				struct {
 					uint8_t	dialog_token;
 					uint8_t	follow_up;
 					uint8_t	tod[6];
 					uint8_t	toa[6];
 					uint16_t tod_error;
 					uint16_t toa_error;
 					uint8_t variable[0];
 				} ftm;
 				/* 802.11-2016, 9.6.5.2 ADDBA Request frame format */
 				struct {
 					uint8_t action_code;
 					uint8_t dialog_token;
 					uint16_t capab;
 					uint16_t timeout;
 					uint16_t start_seq_num;
 					/* Optional follows... */
 					uint8_t variable[0];
 				} addba_req;
 				/* XXX */
 				struct {
 					uint8_t dialog_token;
 				} wnm_timing_msr;
 			} u;
 		} action;
+		DECLARE_FLEX_ARRAY(uint8_t, body);
 	} u;
 };
 
 struct ieee80211_cts {		/* net80211::ieee80211_frame_cts */
         __le16		frame_control;
         __le16		duration;
 	uint8_t		ra[ETH_ALEN];
 } __packed;
 
 struct ieee80211_rts {		/* net80211::ieee80211_frame_rts */
         __le16		frame_control;
         __le16		duration;
 	uint8_t		ra[ETH_ALEN];
 	uint8_t		ta[ETH_ALEN];
 } __packed;
 
 #define	MHZ_TO_KHZ(_f)		((_f) * 1000)
 #define	DBI_TO_MBI(_g)		((_g) * 100)
 #define	MBI_TO_DBI(_x)		((_x) / 100)
 #define	DBM_TO_MBM(_g)		((_g) * 100)
 #define	MBM_TO_DBM(_x)		((_x) / 100)
 
 #define	IEEE80211_SEQ_TO_SN(_seqn)	(((_seqn) & IEEE80211_SEQ_SEQ_MASK) >> \
 					    IEEE80211_SEQ_SEQ_SHIFT)
+#define	IEEE80211_SN_TO_SEQ(_sn)	(((_sn) << IEEE80211_SEQ_SEQ_SHIFT) & \
+					    IEEE80211_SEQ_SEQ_MASK)
 
 /* Time unit (TU) to .. See net80211: IEEE80211_DUR_TU */
 #define	TU_TO_JIFFIES(_tu)	(usecs_to_jiffies(_tu) * 1024)
 #define	TU_TO_EXP_TIME(_tu)	(jiffies + TU_TO_JIFFIES(_tu))
 
 /* 9.4.2.21.1, Table 9-82. */
 #define	IEEE80211_SPCT_MSR_RPRT_TYPE_LCI	8
 #define	IEEE80211_SPCT_MSR_RPRT_TYPE_CIVIC	11
 
 /* 9.4.2.1, Table 9-77. Element IDs. */
 enum ieee80211_eid {
 	WLAN_EID_SSID				= 0,
 	WLAN_EID_SUPP_RATES			= 1,
 	WLAN_EID_DS_PARAMS			= 3,
 	WLAN_EID_TIM				= 5,
 	WLAN_EID_COUNTRY			= 7,	/* IEEE80211_ELEMID_COUNTRY */
 	WLAN_EID_REQUEST			= 10,
 	WLAN_EID_CHANNEL_SWITCH			= 37,
 	WLAN_EID_MEASURE_REPORT			= 39,
 	WLAN_EID_HT_CAPABILITY			= 45,	/* IEEE80211_ELEMID_HTCAP */
 	WLAN_EID_RSN				= 48,	/* IEEE80211_ELEMID_RSN */
 	WLAN_EID_EXT_SUPP_RATES			= 50,
 	WLAN_EID_EXT_NON_INHERITANCE		= 56,
 	WLAN_EID_EXT_CHANSWITCH_ANN		= 60,
 	WLAN_EID_MULTIPLE_BSSID			= 71,	/* IEEE80211_ELEMID_MULTIBSSID */
 	WLAN_EID_MULTI_BSSID_IDX		= 85,
 	WLAN_EID_EXT_CAPABILITY			= 127,
 	WLAN_EID_VHT_CAPABILITY			= 191,	/* IEEE80211_ELEMID_VHT_CAP */
 	WLAN_EID_VENDOR_SPECIFIC		= 221,	/* IEEE80211_ELEMID_VENDOR */
 };
 
 enum ieee80211_eid_ext {
 	WLAN_EID_EXT_HE_CAPABILITY		= 35,
 };
 
 #define	for_each_element(_elem, _data, _len) \
 	for (_elem = (const struct element *)(_data); \
 	    (((const uint8_t *)(_data) + (_len) - (const uint8_t *)_elem) >= sizeof(*_elem)) && \
 		(((const uint8_t *)(_data) + (_len) - (const uint8_t *)_elem) >= (sizeof(*_elem) + _elem->datalen)); \
 	    _elem = (const struct element *)(_elem->data + _elem->datalen))
 
 #define	for_each_element_id(_elem, _eid, _data, _len) \
 	for_each_element(_elem, _data, _len) \
 		if (_elem->id == (_eid))
 
 /* 9.4.1.7, Table 9-45. Reason codes. */
 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,
 };
 
 /* 9.4.1.9, Table 9-46. Status codes. */
 enum ieee80211_status_code {
 	WLAN_STATUS_SUCCESS			= 0,
 	WLAN_STATUS_AUTH_TIMEOUT		= 16,	/* REJECTED_SEQUENCE_TIMEOUT */
 };
 
 /* 9.3.1.22 Trigger frame format; 80211ax-2021 */
 struct ieee80211_trigger {
         __le16		frame_control;
         __le16		duration_id;
 	uint8_t		ra[ETH_ALEN];
 	uint8_t		ta[ETH_ALEN];
 	__le64		common_info;		/* 8+ really */
 	uint8_t		variable[];
 };
 
 /* Table 9-29c-Trigger Type subfield encoding */
 enum {
 	IEEE80211_TRIGGER_TYPE_BASIC		= 0x0,
+	IEEE80211_TRIGGER_TYPE_MU_BAR		= 0x2,
 #if 0
 	/* Not seen yet. */
 	BFRP					= 0x1,
-	MU-BAR					= 0x2,
 	MU-RTS					= 0x3,
 	BSRP					= 0x4,
 	GCR MU-BAR				= 0x5,
 	BQRP					= 0x6,
 	NFRP					= 0x7,
 	/* 0x8..0xf reserved */
 #endif
 	IEEE80211_TRIGGER_TYPE_MASK		= 0xf
 };
 
+#define	IEEE80211_TRIGGER_ULBW_MASK		0xc0000
+#define	IEEE80211_TRIGGER_ULBW_20MHZ		0x0
+#define	IEEE80211_TRIGGER_ULBW_40MHZ		0x1
+#define	IEEE80211_TRIGGER_ULBW_80MHZ		0x2
+#define	IEEE80211_TRIGGER_ULBW_160_80P80MHZ	0x3
+
 /* 802.11-2020, Figure 9-687-Control field format; 802.11ax-2021 */
 #define	IEEE80211_TWT_CONTROL_NEG_TYPE_BROADCAST	BIT(3)
 #define	IEEE80211_TWT_CONTROL_RX_DISABLED		BIT(4)
 #define	IEEE80211_TWT_CONTROL_WAKE_DUR_UNIT		BIT(5)
 
 /* 802.11-2020, Figure 9-688-Request Type field format; 802.11ax-2021 */
 #define	IEEE80211_TWT_REQTYPE_SETUP_CMD		(BIT(1) | BIT(2) | BIT(3))
 #define	IEEE80211_TWT_REQTYPE_TRIGGER		BIT(4)
 #define	IEEE80211_TWT_REQTYPE_IMPLICIT		BIT(5)
 #define	IEEE80211_TWT_REQTYPE_FLOWTYPE		BIT(6)
 #define	IEEE80211_TWT_REQTYPE_FLOWID		(BIT(7) | BIT(8) | BIT(9))
 #define	IEEE80211_TWT_REQTYPE_WAKE_INT_EXP	(BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14))
 #define	IEEE80211_TWT_REQTYPE_PROTECTION	BIT(15)
 
 struct ieee80211_twt_params {
 	int	mantissa, min_twt_dur, twt;
 	uint16_t				req_type;
 };
 
 struct ieee80211_twt_setup {
 	int	control;
 	struct ieee80211_twt_params		*params;
 };
 
 /* 802.11-2020, Table 9-297-TWT Setup Command field values */
 enum ieee80211_twt_setup_cmd {
 	TWT_SETUP_CMD_REQUEST			= 0,
 	TWT_SETUP_CMD_SUGGEST			= 1,
 	/* DEMAND				= 2, */
 	/* GROUPING				= 3, */
 	TWT_SETUP_CMD_ACCEPT			= 4,
 	/* ALTERNATE				= 5 */
 	TWT_SETUP_CMD_DICTATE			= 6,
 	TWT_SETUP_CMD_REJECT			= 7,
 };
 
 struct ieee80211_bssid_index {
 	int	bssid_index;
 };
 
-enum ieee80211_reg_ap_power {
+enum ieee80211_ap_reg_power {
+	IEEE80211_REG_UNSET_AP,
 	IEEE80211_REG_LPI_AP,
 	IEEE80211_REG_SP_AP,
 	IEEE80211_REG_VLP_AP,
 };
 
+/*
+ * 802.11ax-2021, Table 9-277-Meaning of Maximum Transmit Power Count subfield
+ * if Maximum Transmit Power Interpretation subfield is 1 or 3
+ */
+#define	IEEE80211_MAX_NUM_PWR_LEVEL		8
+
+/*
+ * 802.11ax-2021, Table 9-275a-Maximum Transmit Power Interpretation subfield
+ * encoding (4) * Table E-12-Regulatory Info subfield encoding in the
+ * United States (2)
+ */
+#define	IEEE80211_TPE_MAX_IE_NUM		8
+
+/* 802.11ax-2021, 9.4.2.161 Transmit Power Envelope element */
+struct ieee80211_tx_pwr_env {
+	uint8_t		tx_power_info;
+	uint8_t		tx_power[IEEE80211_MAX_NUM_PWR_LEVEL];
+};
+
+/* 802.11ax-2021, Figure 9-617-Transmit Power Information field format */
+/* These are field masks (3bit/3bit/2bit). */
+#define	IEEE80211_TX_PWR_ENV_INFO_COUNT		0x07
+#define	IEEE80211_TX_PWR_ENV_INFO_INTERPRET	0x38
+#define	IEEE80211_TX_PWR_ENV_INFO_CATEGORY	0xc0
+
+/*
+ * 802.11ax-2021, Table 9-275a-Maximum Transmit Power Interpretation subfield
+ * encoding
+ */
+enum ieee80211_tx_pwr_interpretation_subfield_enc {
+	IEEE80211_TPE_LOCAL_EIRP,
+	IEEE80211_TPE_LOCAL_EIRP_PSD,
+	IEEE80211_TPE_REG_CLIENT_EIRP,
+	IEEE80211_TPE_REG_CLIENT_EIRP_PSD,
+};
+
+
 /* net80211: IEEE80211_IS_CTL() */
 static __inline bool
 ieee80211_is_ctl(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_TYPE_CTL);
 
 	return (fc == v);
 }
 
 /* net80211: IEEE80211_IS_DATA() */
 static __inline bool
 ieee80211_is_data(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_TYPE_DATA);
 
 	return (fc == v);
 }
 
 /* net80211: IEEE80211_IS_QOSDATA() */
 static __inline bool
 ieee80211_is_data_qos(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_QOS_DATA | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_QOS_DATA | IEEE80211_FC0_TYPE_DATA);
 
 	return (fc == v);
 }
 
 /* net80211: IEEE80211_IS_MGMT() */
 static __inline bool
 ieee80211_is_mgmt(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_TYPE_MGT);
 
 	return (fc == v);
 }
 
 
 /* Derived from net80211::ieee80211_anyhdrsize. */
 static __inline unsigned int
 ieee80211_hdrlen(__le16 fc)
 {
 	unsigned int size;
 
 	if (ieee80211_is_ctl(fc)) {
 		switch (fc & htole16(IEEE80211_FC0_SUBTYPE_MASK)) {
 		case htole16(IEEE80211_FC0_SUBTYPE_CTS):
 		case htole16(IEEE80211_FC0_SUBTYPE_ACK):
 			return sizeof(struct ieee80211_frame_ack);
 		case htole16(IEEE80211_FC0_SUBTYPE_BAR):
 			return sizeof(struct ieee80211_frame_bar);
 		}
 		return (sizeof(struct ieee80211_frame_min));
 	}
 
 	size = sizeof(struct ieee80211_frame);
 	if (ieee80211_is_data(fc)) {
 		if ((fc & htole16(IEEE80211_FC1_DIR_MASK << 8)) ==
 		    htole16(IEEE80211_FC1_DIR_DSTODS << 8))
 			size += IEEE80211_ADDR_LEN;
 		if ((fc & htole16(IEEE80211_FC0_SUBTYPE_QOS_DATA |
 		    IEEE80211_FC0_TYPE_MASK)) ==
 		    htole16(IEEE80211_FC0_SUBTYPE_QOS_DATA |
 		    IEEE80211_FC0_TYPE_DATA))
 			size += sizeof(uint16_t);
 	}
 
 	if (ieee80211_is_mgmt(fc)) {
 #ifdef __notyet__
 		printf("XXX-BZ %s: TODO? fc %#04x size %u\n",
 		    __func__, fc, size);
 #endif
 		;
 	}
 
 	return (size);
 }
 
 static inline bool
 ieee80211_is_trigger(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_TRIGGER | IEEE80211_FC0_TYPE_CTL);
 
 	return (fc == v);
 }
 
 #endif	/* _LINUXKPI_LINUX_IEEE80211_H */
diff --git a/sys/compat/linuxkpi/common/include/linux/nl80211.h b/sys/compat/linuxkpi/common/include/linux/nl80211.h
index 5b43ff675e19..6916957731e2 100644
--- a/sys/compat/linuxkpi/common/include/linux/nl80211.h
+++ b/sys/compat/linuxkpi/common/include/linux/nl80211.h
@@ -1,424 +1,440 @@
 /*-
- * Copyright (c) 2020-2023 The FreeBSD Foundation
+ * Copyright (c) 2020-2024 The FreeBSD Foundation
  *
  * 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.
  */
 
 #ifndef	_LINUXKPI_LINUX_NL80211_H
 #define	_LINUXKPI_LINUX_NL80211_H
 
 #include <linux/bitops.h>
 
 enum nl80211_feature_flags {
 	NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE	= BIT(0),
 	NL80211_FEATURE_DS_PARAM_SET_IE_IN_PROBES	= BIT(1),
 	NL80211_FEATURE_HT_IBSS				= BIT(2),
 	NL80211_FEATURE_LOW_PRIORITY_SCAN		= BIT(3),
 	NL80211_FEATURE_ND_RANDOM_MAC_ADDR		= BIT(4),
 	NL80211_FEATURE_P2P_GO_CTWIN			= BIT(5),
 	NL80211_FEATURE_P2P_GO_OPPPS			= BIT(6),
 	NL80211_FEATURE_QUIET				= BIT(7),
 	NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR		= BIT(8),
 	NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR	= BIT(9),
 	NL80211_FEATURE_DYNAMIC_SMPS			= BIT(10),
 	NL80211_FEATURE_STATIC_SMPS			= BIT(11),
 	NL80211_FEATURE_SUPPORTS_WMM_ADMISSION		= BIT(12),
 	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),
 	NL80211_FEATURE_ACTIVE_MONITOR			= BIT(17),
 };
 
 enum nl80211_pmsr_ftm_failure_flags {
 	NL80211_PMSR_FTM_FAILURE_NO_RESPONSE		= BIT(0),
 	NL80211_PMSR_FTM_FAILURE_PEER_BUSY		= BIT(1),
 	NL80211_PMSR_FTM_FAILURE_UNSPECIFIED		= BIT(2),
 };
 
 enum nl80211_pmsr_status_flags {
 	NL80211_PMSR_STATUS_FAILURE			= BIT(0),
 	NL80211_PMSR_STATUS_SUCCESS			= BIT(1),
 	NL80211_PMSR_STATUS_TIMEOUT			= BIT(2),
 };
 
 #define	NL80211_PMSR_TYPE_FTM				1
 
 enum nl80211_reg_rule_flags {
 	NL80211_RRF_AUTO_BW				= BIT(0),
 	NL80211_RRF_DFS					= BIT(1),
 	NL80211_RRF_GO_CONCURRENT			= BIT(2),
 	NL80211_RRF_NO_IR				= BIT(3),
 	NL80211_RRF_NO_OUTDOOR				= BIT(4),
 	NL80211_RRF_NO_HT40MINUS			= BIT(5),
 	NL80211_RRF_NO_HT40PLUS				= BIT(6),
 	NL80211_RRF_NO_80MHZ				= BIT(7),
 	NL80211_RRF_NO_160MHZ				= BIT(8),
 	NL80211_RRF_NO_HE				= BIT(9),
 	NL80211_RRF_NO_OFDM				= BIT(10),
 	NL80211_RRF_NO_320MHZ				= BIT(11),
 	NL80211_RRF_NO_EHT				= BIT(12),
+	NL80211_RRF_DFS_CONCURRENT			= BIT(13),
+	NL80211_RRF_NO_6GHZ_VLP_CLIENT			= BIT(14),
+	NL80211_RRF_NO_6GHZ_AFC_CLIENT			= BIT(15),
+	NL80211_RRF_PSD					= BIT(16),
 };
 #define	NL80211_RRF_NO_HT40	(NL80211_RRF_NO_HT40MINUS|NL80211_RRF_NO_HT40PLUS)
 
 enum nl80211_scan_flags {
 	NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME		= BIT(0),
 	NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION	= BIT(1),
 	NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE	= BIT(2),
 	NL80211_SCAN_FLAG_RANDOM_ADDR			= BIT(3),
 	NL80211_SCAN_FLAG_COLOCATED_6GHZ		= BIT(4),
 	NL80211_SCAN_FLAG_RANDOM_SN			= BIT(5),
 	NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP	= BIT(6),
 };
 
 #define	NL80211_MAX_SUPP_REG_RULES			512	/* TODO FIXME, random */
 
 #define	NL80211_BSS_CHAN_WIDTH_20			__LINE__ /* TODO FIXME, brcmfmac */
 
 enum nl80211_wpa_versions {
 	NL80211_WPA_VERSION_1	= 1,
 	NL80211_WPA_VERSION_2,
 	NL80211_WPA_VERSION_3,
 };
 
 enum nl80211_bss_select_attr {
 	__NL80211_BSS_SELECT_ATTR_INVALID	= 0,
 	NL80211_BSS_SELECT_ATTR_BAND_PREF,
 	NL80211_BSS_SELECT_ATTR_RSSI,
 	NL80211_BSS_SELECT_ATTR_RSSI_ADJUST,
 };
 
 enum nl80211_sta_flag {
 	/* XXX TODO */
 	NL80211_STA_FLAG_ASSOCIATED,
 	NL80211_STA_FLAG_AUTHENTICATED,
 	NL80211_STA_FLAG_AUTHORIZED,
 	NL80211_STA_FLAG_TDLS_PEER,
 	NL80211_STA_FLAG_WME,
 };
 
 enum nl80211_band {
 	/* XXX TODO */
 	NL80211_BAND_2GHZ	= 0,
 	NL80211_BAND_5GHZ,
 	NL80211_BAND_60GHZ,
 	NL80211_BAND_6GHZ,
 
 	/* Keep this last. */
 	NUM_NL80211_BANDS
 };
 
 enum nl80211_chan_flags {
 	/* XXX TODO */
 	NL80211_CHAN_NO_HT,
 };
 
 enum nl80211_chan_width {
 	/* XXX TODO */
 	NL80211_CHAN_WIDTH_20_NOHT,
 	NL80211_CHAN_WIDTH_20,
 	NL80211_CHAN_WIDTH_40,
 	NL80211_CHAN_WIDTH_80,
 	NL80211_CHAN_WIDTH_80P80,
 	NL80211_CHAN_WIDTH_160,
 	NL80211_CHAN_WIDTH_5,
 	NL80211_CHAN_WIDTH_10,
 	NL80211_CHAN_WIDTH_320,
 };
 
 enum nl80211_iftype {
 	/* XXX TODO */
 	NL80211_IFTYPE_UNSPECIFIED,
 	NL80211_IFTYPE_ADHOC,
 	NL80211_IFTYPE_STATION,
 	NL80211_IFTYPE_AP,
 	NL80211_IFTYPE_AP_VLAN,
 	NL80211_IFTYPE_MONITOR,
 	NL80211_IFTYPE_P2P_CLIENT,
 	NL80211_IFTYPE_P2P_DEVICE,
 	NL80211_IFTYPE_P2P_GO,
 	NL80211_IFTYPE_MESH_POINT,
 	NL80211_IFTYPE_WDS,
 	NL80211_IFTYPE_OCB,
 	NL80211_IFTYPE_NAN,
 
 	/* Keep this last. */
 	NUM_NL80211_IFTYPES
 };
 
 enum nl80211_preamble {
 	/* XXX TODO */
 	NL80211_PREAMBLE_LEGACY,
 	NL80211_PREAMBLE_HT,
 	NL80211_PREAMBLE_VHT,
 	NL80211_PREAMBLE_HE,
 };
 
 enum nl80211_tdls_operation {
 	/* XXX TODO */
 	NL80211_TDLS_SETUP,
 	NL80211_TDLS_TEARDOWN,
 	NL80211_TDLS_ENABLE_LINK,
 	NL80211_TDLS_DISABLE_LINK,
 	NL80211_TDLS_DISCOVERY_REQ,
 	NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY,
 	NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY,
 };
 
 enum nl80211_cqm_rssi_threshold_event {
 	/* XXX TODO */
 	NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
 	NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
 };
 
 enum nl80211_ext_feature {
 	/* XXX TODO */
 	NL80211_EXT_FEATURE_ACCEPT_BCAST_PROBE_RESP,
 	NL80211_EXT_FEATURE_BSS_PARENT_TSF,
 	NL80211_EXT_FEATURE_CAN_REPLACE_PTK0,
 	NL80211_EXT_FEATURE_DFS_OFFLOAD,
 	NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER,
 	NL80211_EXT_FEATURE_EXT_KEY_ID,
 	NL80211_EXT_FEATURE_FILS_MAX_CHANNEL_TIME,
 	NL80211_EXT_FEATURE_MU_MIMO_AIR_SNIFFER,
 	NL80211_EXT_FEATURE_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION,
 	NL80211_EXT_FEATURE_OCE_PROBE_REQ_HIGH_TX_RATE,
 	NL80211_EXT_FEATURE_PROTECTED_TWT,
 	NL80211_EXT_FEATURE_SAE_OFFLOAD,
 	NL80211_EXT_FEATURE_SCAN_START_TIME,
 	NL80211_EXT_FEATURE_SET_SCAN_DWELL,
 	NL80211_EXT_FEATURE_VHT_IBSS,
 	NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X,
 	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,
 	NL80211_EXT_FEATURE_BEACON_RATE_LEGACY,
 	NL80211_EXT_FEATURE_BEACON_RATE_HT,
 	NL80211_EXT_FEATURE_BEACON_RATE_VHT,
 	NL80211_EXT_FEATURE_BEACON_RATE_HE,
 	NL80211_EXT_FEATURE_BSS_COLOR,
 	NL80211_EXT_FEATURE_FILS_DISCOVERY,
 	NL80211_EXT_FEATURE_RADAR_BACKGROUND,
 	NL80211_EXT_FEATURE_UNSOL_BCAST_PROBE_RESP,
 	NL80211_EXT_FEATURE_BEACON_PROTECTION,
 	NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT,
 	NL80211_EXT_FEATURE_PUNCT,
+	NL80211_EXT_FEATURE_DFS_CONCURRENT,
+	NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS,
+	NL80211_EXT_FEATURE_SPP_AMSDU_SUPPORT,
+	NL80211_EXT_FEATURE_SECURE_LTF,
+	NL80211_EXT_FEATURE_PROT_RANGE_NEGO_AND_MEASURE,
+	NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK,
+	NL80211_EXT_FEATURE_SAE_OFFLOAD_AP,
 
 	/* Keep this last. */
 	NUM_NL80211_EXT_FEATURES
 };
 
 enum nl80211_sta_info {
 	/* XXX TODO */
 	NL80211_STA_INFO_BEACON_RX,
 	NL80211_STA_INFO_BEACON_SIGNAL_AVG,
 	NL80211_STA_INFO_BSS_PARAM,
 	NL80211_STA_INFO_CHAIN_SIGNAL,
+	NL80211_STA_INFO_CHAIN_SIGNAL_AVG,
 	NL80211_STA_INFO_CONNECTED_TIME,
 	NL80211_STA_INFO_INACTIVE_TIME,
 	NL80211_STA_INFO_SIGNAL,
 	NL80211_STA_INFO_SIGNAL_AVG,
 	NL80211_STA_INFO_STA_FLAGS,
 	NL80211_STA_INFO_RX_BITRATE,
 	NL80211_STA_INFO_RX_PACKETS,
 	NL80211_STA_INFO_RX_BYTES,
 	NL80211_STA_INFO_RX_DROP_MISC,
 	NL80211_STA_INFO_TX_BITRATE,
 	NL80211_STA_INFO_TX_PACKETS,
 	NL80211_STA_INFO_TX_BYTES,
 	NL80211_STA_INFO_TX_BYTES64,
 	NL80211_STA_INFO_RX_BYTES64,
 	NL80211_STA_INFO_TX_FAILED,
 	NL80211_STA_INFO_TX_RETRIES,
 	NL80211_STA_INFO_RX_DURATION,
 	NL80211_STA_INFO_TX_DURATION,
 	NL80211_STA_INFO_ACK_SIGNAL,
 	NL80211_STA_INFO_ACK_SIGNAL_AVG,
 };
 
 enum nl80211_ftm_stats {
 	/* XXX TODO */
 	NL80211_FTM_STATS_ASAP_NUM,
 	NL80211_FTM_STATS_FAILED_NUM,
 	NL80211_FTM_STATS_NON_ASAP_NUM,
 	NL80211_FTM_STATS_OUT_OF_WINDOW_TRIGGERS_NUM,
 	NL80211_FTM_STATS_PARTIAL_NUM,
 	NL80211_FTM_STATS_RESCHEDULE_REQUESTS_NUM,
 	NL80211_FTM_STATS_SUCCESS_NUM,
 	NL80211_FTM_STATS_TOTAL_DURATION_MSEC,
 	NL80211_FTM_STATS_UNKNOWN_TRIGGERS_NUM,
 };
 
 enum nl80211_reg_initiator {
 	/* XXX TODO */
 	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 {
 	/* XXX TODO */
 	int     mask, set;
 
 };
 
 enum nl80211_tx_power_setting {
 	/* XXX TODO */
 	NL80211_TX_POWER_AUTOMATIC,
 	NL80211_TX_POWER_FIXED,
 	NL80211_TX_POWER_LIMITED,
 };
 
 enum nl80211_crit_proto_id {
 	/* XXX TODO */
 	NL80211_CRIT_PROTO_DHCP,
 };
 
 enum nl80211_auth_type {
 	NL80211_AUTHTYPE_AUTOMATIC,
 	NL80211_AUTHTYPE_OPEN_SYSTEM,
 	NL80211_AUTHTYPE_SHARED_KEY,
 	NL80211_AUTHTYPE_SAE,
 };
 
 enum nl80211_key_type {
 	NL80211_KEYTYPE_GROUP,
 	NL80211_KEYTYPE_PAIRWISE,
 };
 
 enum nl80211_he_ru_alloc {
 	NL80211_RATE_INFO_HE_RU_ALLOC_26,
 	NL80211_RATE_INFO_HE_RU_ALLOC_52,
 	NL80211_RATE_INFO_HE_RU_ALLOC_106,
 	NL80211_RATE_INFO_HE_RU_ALLOC_242,
 	NL80211_RATE_INFO_HE_RU_ALLOC_484,
 	NL80211_RATE_INFO_HE_RU_ALLOC_996,
 	NL80211_RATE_INFO_HE_RU_ALLOC_2x996,
 };
 
 enum nl80211_he_gi {
 	NL80211_RATE_INFO_HE_GI_0_8,
 	NL80211_RATE_INFO_HE_GI_1_6,
 	NL80211_RATE_INFO_HE_GI_3_2,
 };
 
 enum nl80211_he_ltf {
 	NL80211_RATE_INFO_HE_1XLTF,
 	NL80211_RATE_INFO_HE_2XLTF,
 	NL80211_RATE_INFO_HE_4XLTF,
 };
 
 enum nl80211_eht_gi {
 	NL80211_RATE_INFO_EHT_GI_0_8,
 	NL80211_RATE_INFO_EHT_GI_1_6,
 	NL80211_RATE_INFO_EHT_GI_3_2,
 };
 
 enum nl80211_eht_ru_alloc {
 	NL80211_RATE_INFO_EHT_RU_ALLOC_26,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_52,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_52P26,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_106,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_106P26,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_242,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_484,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_484P242,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_996,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_996P484,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_996P484P242,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_2x996,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_2x996P484,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_3x996,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_3x996P484,
 	NL80211_RATE_INFO_EHT_RU_ALLOC_4x996,
 };
 
 enum nl80211_dfs_regions {
 	NL80211_DFS_UNSET,
 	NL80211_DFS_FCC,
 	NL80211_DFS_ETSI,
 	NL80211_DFS_JP,
 };
 
 enum nl80211_dfs_state {
 	NL80211_DFS_USABLE,
 };
 
 enum nl80211_sar_type {
 	NL80211_SAR_TYPE_POWER,
 };
 
 #define	NL80211_VHT_NSS_MAX			8
 #define	NL80211_HE_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,
 	NL80211_TID_CONFIG_ATTR_AMSDU_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_DEFAULT_GI,
 	NL80211_TXRATE_FORCE_SGI,
 	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,
 };
 
 enum nl80211_user_reg_hint_type {
 	NL80211_USER_REG_HINT_USER,
 };
 
+enum nl80211_hidden_ssid {
+	NL80211_HIDDEN_SSID_NOT_IN_USE,
+};
+
 #define	NL80211_KCK_LEN				16
 #define	NL80211_KCK_EXT_LEN			24
 #define	NL80211_KEK_LEN				16
 #define	NL80211_KEK_EXT_LEN			32
 #define	NL80211_REPLAY_CTR_LEN			8
 #endif	/* _LINUXKPI_LINUX_NL80211_H */
diff --git a/sys/compat/linuxkpi/common/include/net/mac80211.h b/sys/compat/linuxkpi/common/include/net/mac80211.h
index c102ada6def2..29fb335a8db9 100644
--- a/sys/compat/linuxkpi/common/include/net/mac80211.h
+++ b/sys/compat/linuxkpi/common/include/net/mac80211.h
@@ -1,2717 +1,2717 @@
 /*-
  * Copyright (c) 2020-2023 The FreeBSD Foundation
  * Copyright (c) 2020-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.
  */
 
 #ifndef	_LINUXKPI_NET_MAC80211_H
 #define	_LINUXKPI_NET_MAC80211_H
 
 #include <sys/types.h>
 
 #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>
 #include <linux/dcache.h>
 #include <net/cfg80211.h>
 
 #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)
 
 #define	IEEE80211_LINK_UNSPECIFIED		0x0f
 
 /* hw->conf.flags */
 enum ieee80211_hw_conf_flags {
 	IEEE80211_CONF_IDLE			= BIT(0),
 	IEEE80211_CONF_PS			= BIT(1),
 	IEEE80211_CONF_MONITOR			= BIT(2),
 	IEEE80211_CONF_OFFCHANNEL		= BIT(3),
 };
 
 /* (*ops->config()) */
 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),
 	IEEE80211_CONF_CHANGE_POWER		= BIT(4),
 };
 
 #define	CFG80211_TESTMODE_CMD(_x)	/* XXX TODO */
 #define	CFG80211_TESTMODE_DUMP(_x)	/* XXX TODO */
 
 #define	FCS_LEN				4
 
 /* ops.configure_filter() */
 enum mcast_filter_flags {
 	FIF_ALLMULTI			= BIT(0),
 	FIF_PROBE_REQ			= BIT(1),
 	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 {
 	BSS_CHANGED_ARP_FILTER		= BIT(0),
 	BSS_CHANGED_ASSOC		= BIT(1),
 	BSS_CHANGED_BANDWIDTH		= BIT(2),
 	BSS_CHANGED_BEACON		= BIT(3),
 	BSS_CHANGED_BEACON_ENABLED	= BIT(4),
 	BSS_CHANGED_BEACON_INFO		= BIT(5),
 	BSS_CHANGED_BEACON_INT		= BIT(6),
 	BSS_CHANGED_BSSID		= BIT(7),
 	BSS_CHANGED_CQM			= BIT(8),
 	BSS_CHANGED_ERP_CTS_PROT	= BIT(9),
 	BSS_CHANGED_ERP_SLOT		= BIT(10),
 	BSS_CHANGED_FTM_RESPONDER	= BIT(11),
 	BSS_CHANGED_HT			= BIT(12),
 	BSS_CHANGED_IDLE		= BIT(13),
 	BSS_CHANGED_MU_GROUPS		= BIT(14),
 	BSS_CHANGED_P2P_PS		= BIT(15),
 	BSS_CHANGED_PS			= BIT(16),
 	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),
 	BSS_CHANGED_FILS_DISCOVERY	= BIT(26),
 	BSS_CHANGED_HE_OBSS_PD		= BIT(27),
 	BSS_CHANGED_TWT			= BIT(28),
 	BSS_CHANGED_UNSOL_BCAST_PROBE_RESP = BIT(30),
 	BSS_CHANGED_EHT_PUNCTURING	= BIT(31),
 };
 
 /* 802.11 Figure 9-256 Suite selector format. [OUI(3), SUITE TYPE(1)] */
 #define	WLAN_CIPHER_SUITE_OUI(_oui, _x)	(((_oui) << 8) | ((_x) & 0xff))
 
 /* 802.11 Table 9-131 Cipher suite selectors. */
 /* 802.1x suite B			11 */
 #define	WLAN_CIPHER_SUITE(_x)		WLAN_CIPHER_SUITE_OUI(0x000fac, _x)
 /* Use group				0 */
 #define	WLAN_CIPHER_SUITE_WEP40		WLAN_CIPHER_SUITE(1)
 #define	WLAN_CIPHER_SUITE_TKIP		WLAN_CIPHER_SUITE(2)
 /* Reserved				3 */
 #define	WLAN_CIPHER_SUITE_CCMP		WLAN_CIPHER_SUITE(4)	/* CCMP-128 */
 #define	WLAN_CIPHER_SUITE_WEP104	WLAN_CIPHER_SUITE(5)
 #define	WLAN_CIPHER_SUITE_AES_CMAC	WLAN_CIPHER_SUITE(6)	/* BIP-CMAC-128 */
 /* Group addressed traffic not allowed	7 */
 #define	WLAN_CIPHER_SUITE_GCMP		WLAN_CIPHER_SUITE(8)
 #define	WLAN_CIPHER_SUITE_GCMP_256	WLAN_CIPHER_SUITE(9)
 #define	WLAN_CIPHER_SUITE_CCMP_256	WLAN_CIPHER_SUITE(10)
 #define	WLAN_CIPHER_SUITE_BIP_GMAC_128	WLAN_CIPHER_SUITE(11)
 #define	WLAN_CIPHER_SUITE_BIP_GMAC_256	WLAN_CIPHER_SUITE(12)
 #define	WLAN_CIPHER_SUITE_BIP_CMAC_256	WLAN_CIPHER_SUITE(13)
 /* Reserved				14-255 */
 
 /* See ISO/IEC JTC 1 N 9880 Table 11 */
 #define	WLAN_CIPHER_SUITE_SMS4		WLAN_CIPHER_SUITE_OUI(0x001472, 1)
 
 
 /* 802.11 Table 9-133 AKM suite selectors. */
 #define	WLAN_AKM_SUITE(_x)		WLAN_CIPHER_SUITE_OUI(0x000fac, _x)
 /* Reserved				0 */
 #define	WLAN_AKM_SUITE_8021X		WLAN_AKM_SUITE(1)
 #define	WLAN_AKM_SUITE_PSK		WLAN_AKM_SUITE(2)
 #define	WLAN_AKM_SUITE_FT_8021X		WLAN_AKM_SUITE(3)
 #define	WLAN_AKM_SUITE_FT_PSK		WLAN_AKM_SUITE(4)
 #define	WLAN_AKM_SUITE_8021X_SHA256	WLAN_AKM_SUITE(5)
 #define	WLAN_AKM_SUITE_PSK_SHA256	WLAN_AKM_SUITE(6)
 /* TDLS					7 */
 #define	WLAN_AKM_SUITE_SAE		WLAN_AKM_SUITE(8)
 /* FToSAE				9 */
 /* AP peer key				10 */
 /* 802.1x suite B			11 */
 /* 802.1x suite B 384			12 */
 /* FTo802.1x 384			13 */
 /* Reserved				14-255 */
 /* Apparently 11ax defines more. Seen (19,20) mentioned. */
 
 #define	TKIP_PN_TO_IV16(_x)		((uint16_t)(_x & 0xffff))
 #define	TKIP_PN_TO_IV32(_x)		((uint32_t)((_x >> 16) & 0xffffffff))
 
 struct ieee80211_sta;
 
 /* 802.11-2020 9.4.2.55.3 A-MPDU Parameters field */
 #define	IEEE80211_HT_AMPDU_PARM_FACTOR		0x3
 #define	IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT	2
 #define	IEEE80211_HT_AMPDU_PARM_DENSITY		(0x7 << IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT)
 
 struct ieee80211_ampdu_params {
 	struct ieee80211_sta			*sta;
 	enum ieee80211_ampdu_mlme_action	action;
 	uint16_t				buf_size;
 	uint16_t				timeout;
 	uint16_t				ssn;
 	uint8_t					tid;
 	bool					amsdu;
 };
 
 struct ieee80211_bar {
 	/* TODO FIXME */
 	int		control, start_seq_num;
 	uint8_t		*ra;
 	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 */
 	uint16_t				tim_offset;
 	uint16_t				cntdwn_counter_offs[2];
 
 	int	mbssid_off;
 };
 
 struct mac80211_fils_discovery {
 	uint32_t				max_interval;
 };
 
 struct ieee80211_chanctx_conf {
 	/* TODO FIXME */
 	int		rx_chains_dynamic, rx_chains_static;
 	bool					radar_enabled;
 	struct cfg80211_chan_def		def;
 	struct cfg80211_chan_def		min_def;
 
 	/* Must stay last. */
 	uint8_t					drv_priv[0] __aligned(CACHE_LINE_SIZE);
 };
 
 struct ieee80211_rate_status {
 	struct rate_info			rate_idx;
 	uint8_t					try_count;
 };
 
 struct ieee80211_ema_beacons {
 	uint8_t					cnt;
 	struct {
 		struct sk_buff			*skb;
 		struct ieee80211_mutable_offsets offs;
 	} bcn[0];
 };
 
 #define	WLAN_MEMBERSHIP_LEN			(8)
 #define	WLAN_USER_POSITION_LEN			(16)
 
 struct ieee80211_bss_conf {
 	/* TODO FIXME */
 	struct ieee80211_vif			*vif;
 	const uint8_t				*bssid;
 	uint8_t					addr[ETH_ALEN];
 	uint8_t					link_id;
 	uint8_t					_pad0;
 	uint8_t					transmitter_bssid[ETH_ALEN];
 	struct ieee80211_ftm_responder_params	*ftmr_params;
 	struct ieee80211_p2p_noa_attr		p2p_noa_attr;
 	struct cfg80211_chan_def		chandef;
 	__be32					arp_addr_list[1];	/* XXX TODO */
 	struct ieee80211_rate			*beacon_rate;
 	struct {
 		uint8_t membership[WLAN_MEMBERSHIP_LEN];
 		uint8_t position[WLAN_USER_POSITION_LEN];
 	}  mu_group;
 	struct {
 		uint32_t			params;
 		/* single field struct? */
 	} he_oper;
 	struct cfg80211_he_bss_color		he_bss_color;
 	struct ieee80211_he_obss_pd		he_obss_pd;
 
 	bool					ht_ldpc;
 	bool					vht_ldpc;
 	bool					he_ldpc;
 	bool					vht_mu_beamformee;
 	bool					vht_mu_beamformer;
 	bool					vht_su_beamformee;
 	bool					vht_su_beamformer;
 	bool					he_mu_beamformer;
 	bool					he_su_beamformee;
 	bool					he_su_beamformer;
 	bool					he_full_ul_mumimo;
 	bool					eht_su_beamformee;
 	bool					eht_su_beamformer;
 	bool					eht_mu_beamformer;
 
 	uint16_t				ht_operation_mode;
 	int					arp_addr_cnt;
 	uint16_t				eht_puncturing;
 
 	uint8_t					dtim_period;
 	uint8_t					sync_dtim_count;
 	bool					qos;
 	bool					twt_broadcast;
 	bool					use_cts_prot;
 	bool					use_short_preamble;
 	bool					use_short_slot;
 	bool					he_support;
 	bool					eht_support;
 	bool					csa_active;
 	bool					mu_mimo_owner;
 	uint32_t				sync_device_ts;
 	uint64_t				sync_tsf;
 	uint16_t				beacon_int;
 	int16_t					txpower;
 	uint32_t				basic_rates;
 	int					mcast_rate[NUM_NL80211_BANDS];
-	enum ieee80211_reg_ap_power 		power_type;
+	enum ieee80211_ap_reg_power 		power_type;
 	struct cfg80211_bitrate_mask		beacon_tx_rate;
 	struct mac80211_fils_discovery		fils_discovery;
 	struct ieee80211_chanctx_conf		*chanctx_conf;
 	struct ieee80211_vif			*mbssid_tx_vif;
 
 	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, twt_protected;
 	int		twt_responder, unsol_bcast_probe_resp_interval;
 	int		color_change_active;
 };
 
 struct ieee80211_channel_switch {
 	/* TODO FIXME */
 	int		block_tx, count, delay, device_timestamp, timestamp;
 	struct cfg80211_chan_def		chandef;
 };
 
 struct ieee80211_cipher_scheme {
 	uint32_t	cipher;
 	uint8_t		iftype;		/* We do not know the size of this. */
 	uint8_t		hdr_len;
 	uint8_t		pn_len;
 	uint8_t		pn_off;
 	uint8_t		key_idx_off;
 	uint8_t		key_idx_mask;
 	uint8_t		key_idx_shift;
 	uint8_t		mic_len;
 };
 
 enum ieee80211_event_type {
 	BA_FRAME_TIMEOUT,
 	BAR_RX_EVENT,
 	MLME_EVENT,
 	RSSI_EVENT,
 };
 
 enum ieee80211_rssi_event_data {
 	RSSI_EVENT_LOW,
 	RSSI_EVENT_HIGH,
 };
 
 enum ieee80211_mlme_event_data {
 	ASSOC_EVENT,
 	AUTH_EVENT,
 	DEAUTH_RX_EVENT,
 	DEAUTH_TX_EVENT,
 };
 
 enum ieee80211_mlme_event_status {
 	MLME_DENIED,
 	MLME_TIMEOUT,
 };
 
 struct ieee80211_mlme_event {
 	enum ieee80211_mlme_event_data		data;
 	enum ieee80211_mlme_event_status	status;
 	int					reason;
 };
 
 struct ieee80211_event {
 	/* TODO FIXME */
 	enum ieee80211_event_type		type;
 	union {
 		struct {
 			int     ssn;
 			struct ieee80211_sta	*sta;
 			uint8_t		 	tid;
 		} ba;
 		struct ieee80211_mlme_event	mlme;
 	} u;
 };
 
 struct ieee80211_ftm_responder_params {
 	/* TODO FIXME */
 	uint8_t					*lci;
 	uint8_t					*civicloc;
 	int					lci_len;
 	int					civicloc_len;
 };
 
 struct ieee80211_he_mu_edca_param_ac_rec {
 	/* TODO FIXME */
 	int		aifsn, ecw_min_max, mu_edca_timer;
 };
 
 struct ieee80211_conf {
 	int					dynamic_ps_timeout;
 	int					power_level;
 	uint32_t				listen_interval;
 	bool					radar_enabled;
 	enum ieee80211_hw_conf_flags		flags;
 	struct cfg80211_chan_def		chandef;
 };
 
 enum ieee80211_hw_flags {
 	IEEE80211_HW_AMPDU_AGGREGATION,
 	IEEE80211_HW_AP_LINK_PS,
 	IEEE80211_HW_BUFF_MMPDU_TXQ,
 	IEEE80211_HW_CHANCTX_STA_CSA,
 	IEEE80211_HW_CONNECTION_MONITOR,
 	IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP,
 	IEEE80211_HW_HAS_RATE_CONTROL,
 	IEEE80211_HW_MFP_CAPABLE,
 	IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR,
 	IEEE80211_HW_REPORTS_TX_ACK_STATUS,
 	IEEE80211_HW_RX_INCLUDES_FCS,
 	IEEE80211_HW_SIGNAL_DBM,
 	IEEE80211_HW_SINGLE_SCAN_ON_ALL_BANDS,
 	IEEE80211_HW_SPECTRUM_MGMT,
 	IEEE80211_HW_STA_MMPDU_TXQ,
 	IEEE80211_HW_SUPPORTS_AMSDU_IN_AMPDU,
 	IEEE80211_HW_SUPPORTS_CLONED_SKBS,
 	IEEE80211_HW_SUPPORTS_DYNAMIC_PS,
 	IEEE80211_HW_SUPPORTS_MULTI_BSSID,
 	IEEE80211_HW_SUPPORTS_ONLY_HE_MULTI_BSSID,
 	IEEE80211_HW_SUPPORTS_PS,
 	IEEE80211_HW_SUPPORTS_REORDERING_BUFFER,
 	IEEE80211_HW_SUPPORTS_VHT_EXT_NSS_BW,
 	IEEE80211_HW_SUPPORT_FAST_XMIT,
 	IEEE80211_HW_TDLS_WIDER_BW,
 	IEEE80211_HW_TIMING_BEACON_ONLY,
 	IEEE80211_HW_TX_AMPDU_SETUP_IN_HW,
 	IEEE80211_HW_TX_AMSDU,
 	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,
 	IEEE80211_HW_SUPPORTS_RX_DECAP_OFFLOAD,
 	IEEE80211_HW_SUPPORTS_TX_ENCAP_OFFLOAD,
 	IEEE80211_HW_SUPPORTS_RC_TABLE,
 	IEEE80211_HW_DETECTS_COLOR_COLLISION,
 
 	/* Keep last. */
 	NUM_IEEE80211_HW_FLAGS
 };
 
 struct ieee80211_hw {
 
 	struct wiphy			*wiphy;
 
 	/* TODO FIXME */
 	int		extra_tx_headroom, weight_multiplier;
 	int		max_rate_tries, max_rates, max_report_rates;
 	struct ieee80211_cipher_scheme	*cipher_schemes;
 	int				n_cipher_schemes;
 	const char			*rate_control_algorithm;
 	struct {
 		uint16_t units_pos;	/* radiotap "spec" is .. inconsistent. */
 		uint16_t accuracy;
 	} radiotap_timestamp;
 	size_t				sta_data_size;
 	size_t				vif_data_size;
 	size_t				chanctx_data_size;
 	size_t				txq_data_size;
 	uint16_t			radiotap_mcs_details;
 	uint16_t			radiotap_vht_details;
 	uint16_t			queues;
 	uint16_t			offchannel_tx_hw_queue;
 	uint16_t			uapsd_max_sp_len;
 	uint16_t			uapsd_queues;
 	uint16_t			max_rx_aggregation_subframes;
 	uint16_t			max_tx_aggregation_subframes;
 	uint16_t			max_tx_fragments;
 	uint16_t			max_listen_interval;
 	uint32_t			extra_beacon_tailroom;
 	netdev_features_t		netdev_features;
 	unsigned long			flags[BITS_TO_LONGS(NUM_IEEE80211_HW_FLAGS)];
 	struct ieee80211_conf		conf;
 
 #if 0	/* leave here for documentation purposes.  This does NOT work. */
 	/* Must stay last. */
 	uint8_t				priv[0] __aligned(CACHE_LINE_SIZE);
 #else
 	void				*priv;
 #endif
 };
 
 enum ieee802111_key_flag {
 	IEEE80211_KEY_FLAG_GENERATE_IV		= BIT(0),
 	IEEE80211_KEY_FLAG_GENERATE_MMIC	= BIT(1),
 	IEEE80211_KEY_FLAG_PAIRWISE		= BIT(2),
 	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),
 	IEEE80211_KEY_FLAG_GENERATE_MMIE	= BIT(7),
 	IEEE80211_KEY_FLAG_RESERVE_TAILROOM	= BIT(8),
 };
 
 struct ieee80211_key_conf {
 	atomic64_t			tx_pn;
 	uint32_t			cipher;
 	uint8_t				icv_len;	/* __unused nowadays? */
 	uint8_t				iv_len;
 	uint8_t				hw_key_idx;	/* Set by drv. */
 	uint8_t				keyidx;
 	uint16_t			flags;
 	int8_t				link_id;	/* signed! */
 	uint8_t				keylen;
 	uint8_t				key[0];		/* Must stay last! */
 };
 
 struct ieee80211_key_seq {
 	/* TODO FIXME */
 	union {
 		struct {
 			uint8_t		seq[IEEE80211_MAX_PN_LEN];
 			uint8_t		seq_len;
 		} hw;
 		struct {
 			uint8_t		pn[IEEE80211_CCMP_PN_LEN];
 		} ccmp;
 		struct {
 			uint8_t		pn[IEEE80211_CCMP_PN_LEN];
 		} aes_cmac;
 		struct {
 			uint8_t		pn[IEEE80211_CCMP_PN_LEN];
 		} aes_gmac;
 		struct {
 			uint32_t	iv32;
 			uint16_t	iv16;
 		} tkip;
 	};
 };
 
 
 enum ieee80211_rx_status_flags {
 	RX_FLAG_ALLOW_SAME_PN		= BIT(0),
 	RX_FLAG_AMPDU_DETAILS		= BIT(1),
 	RX_FLAG_AMPDU_EOF_BIT		= BIT(2),
 	RX_FLAG_AMPDU_EOF_BIT_KNOWN	= BIT(3),
 	RX_FLAG_DECRYPTED		= BIT(4),
 	RX_FLAG_DUP_VALIDATED		= BIT(5),
 	RX_FLAG_FAILED_FCS_CRC		= BIT(6),
 	RX_FLAG_ICV_STRIPPED		= BIT(7),
 	RX_FLAG_MACTIME_PLCP_START	= BIT(8),
 	RX_FLAG_MACTIME_START		= BIT(9),
 	RX_FLAG_MIC_STRIPPED		= BIT(10),
 	RX_FLAG_MMIC_ERROR		= BIT(11),
 	RX_FLAG_MMIC_STRIPPED		= BIT(12),
 	RX_FLAG_NO_PSDU			= BIT(13),
 	RX_FLAG_PN_VALIDATED		= BIT(14),
 	RX_FLAG_RADIOTAP_HE		= BIT(15),
 	RX_FLAG_RADIOTAP_HE_MU		= BIT(16),
 	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),
 	RX_FLAG_8023			= BIT(27),
 	RX_FLAG_RADIOTAP_TLV_AT_END	= BIT(28),
 };
 
 enum mac80211_rx_encoding {
 	RX_ENC_LEGACY		= 0,
 	RX_ENC_HT,
 	RX_ENC_VHT,
 	RX_ENC_HE,
 	RX_ENC_EHT,
 };
 
 struct ieee80211_rx_status {
 	/* TODO FIXME, this is too large. Over-reduce types to u8 where possible. */
 	union {
 		uint64_t			boottime_ns;
 		int64_t				ack_tx_hwtstamp;
 	};
 	uint64_t			mactime;
 	uint32_t			device_timestamp;
 	enum ieee80211_rx_status_flags	flag;
 	uint16_t			freq;
 	uint8_t				encoding:3, bw:4;	/* enum mac80211_rx_encoding, rate_info_bw */	/* See mt76.h */
 	uint8_t				ampdu_reference;
 	uint8_t				band;
 	uint8_t				chains;
 	int8_t				chain_signal[IEEE80211_MAX_CHAINS];
 	int8_t				signal;
 	uint8_t				enc_flags;
 	union {
 		struct {
 			uint8_t		he_ru:3;	/* nl80211::enum nl80211_he_ru_alloc */
 			uint8_t		he_gi:2;	/* nl80211::enum nl80211_he_gi */
 			uint8_t		he_dcm:1;
 		};
 		struct {
 			uint8_t		ru:4;		/* nl80211::enum nl80211_eht_ru_alloc */
 			uint8_t		gi:2;		/* nl80211::enum nl80211_eht_gi */
 		} eht;
 	};
 	bool				link_valid;
 	uint8_t				link_id;	/* very incosistent sizes? */
 	uint8_t				zero_length_psdu_type;
 	uint8_t				nss;
 	uint8_t				rate_idx;
 };
 
 struct ieee80211_tx_status {
 	struct ieee80211_sta		*sta;
 	struct ieee80211_tx_info	*info;
 	int64_t				ack_hwtstamp;
 
 	u8				n_rates;
 	struct ieee80211_rate_status	*rates;
 
 	struct sk_buff			*skb;
 	struct list_head		*free_list;
 };
 
 struct ieee80211_scan_ies {
 	/* TODO FIXME */
 	int		common_ie_len;
 	int		len[NUM_NL80211_BANDS];
 	uint8_t		*common_ies;
 	uint8_t		*ies[NUM_NL80211_BANDS];
 };
 
 struct ieee80211_scan_request {
 	struct ieee80211_scan_ies	ies;
 	struct cfg80211_scan_request	req;
 };
 
 struct ieee80211_txq {
 	struct ieee80211_sta		*sta;
 	struct ieee80211_vif		*vif;
 	int				ac;
 	uint8_t				tid;
 
 	/* Must stay last. */
 	uint8_t				drv_priv[0] __aligned(CACHE_LINE_SIZE);
 };
 
 struct ieee80211_sta_rates {
 	/* XXX TODO */
 	/* XXX some _rcu thing */
 	struct {
 		int	idx;
 		int	flags;
 	} 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_agg {
 	uint16_t				max_amsdu_len;
 	uint16_t				max_rc_amsdu_len;
 	uint16_t				max_tid_amsdu_len[IEEE80211_NUM_TIDS];
 };
 
 struct ieee80211_link_sta {
 	uint8_t					addr[ETH_ALEN];
 	uint8_t					link_id;
 	uint32_t				supp_rates[NUM_NL80211_BANDS];
 	struct ieee80211_sta_ht_cap		ht_cap;
 	struct ieee80211_sta_vht_cap		vht_cap;
 	struct ieee80211_sta_he_cap		he_cap;
 	struct ieee80211_sta_he_6ghz_capa	he_6ghz_capa;
 	struct ieee80211_sta_eht_cap		eht_cap;
 	uint8_t					rx_nss;
 	enum ieee80211_sta_rx_bw		bandwidth;
 	enum ieee80211_smps_mode		smps_mode;
 	struct ieee80211_sta_agg		agg;
 	struct ieee80211_sta_txpwr		txpwr;
 };
 
 struct ieee80211_sta {
 	/* TODO FIXME */
 	int		max_amsdu_subframes;
 	int		mfp, smps_mode, tdls, tdls_initiator;
 	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? */
 	uint8_t					addr[ETH_ALEN];
 	uint16_t				aid;
 	bool					wme;
 	uint8_t					max_sp;
 	uint8_t					uapsd_queues;
 	uint16_t				valid_links;
 
 	struct ieee80211_link_sta		deflink;
 	struct ieee80211_link_sta		*link[IEEE80211_MLD_MAX_NUM_LINKS];	/* rcu? */
 
 	/* Must stay last. */
 	uint8_t					drv_priv[0] __aligned(CACHE_LINE_SIZE);
 };
 
 struct ieee80211_tdls_ch_sw_params {
 	/* TODO FIXME */
 	int		action_code, ch_sw_tm_ie, status, switch_time, switch_timeout, timestamp;
 	struct ieee80211_sta			*sta;
 	struct cfg80211_chan_def		*chandef;
 	struct sk_buff				*tmpl_skb;
 };
 
 struct ieee80211_tx_control {
 	/* TODO FIXME */
 	struct ieee80211_sta			*sta;
 };
 
 struct ieee80211_tx_queue_params {
 	/* These types are based on iwlwifi FW structs. */
 	uint16_t	cw_min;
 	uint16_t	cw_max;
 	uint16_t	txop;
 	uint8_t		aifs;
 
 	/* TODO FIXME */
 	int		acm, mu_edca, uapsd;
 	struct ieee80211_he_mu_edca_param_ac_rec	mu_edca_param_rec;
 };
 
 struct ieee80211_tx_rate {
 	uint8_t		idx;
 	uint16_t	count:5,
 			flags:11;
 };
 
 enum ieee80211_vif_driver_flags {
 	IEEE80211_VIF_BEACON_FILTER		= BIT(0),
 	IEEE80211_VIF_SUPPORTS_CQM_RSSI		= BIT(1),
 	IEEE80211_VIF_SUPPORTS_UAPSD		= BIT(2),
 	IEEE80211_VIF_DISABLE_SMPS_OVERRIDE	= BIT(3),
 };
 
 #define	IEEE80211_BSS_ARP_ADDR_LIST_LEN		4
 
 struct ieee80211_vif_cfg {
 	uint16_t				aid;
 	uint16_t				eml_cap;
 	uint16_t				eml_med_sync_delay;
 	bool					assoc;
 	bool					ps;
 	bool					idle;
 	bool					ibss_joined;
 	int					arp_addr_cnt;
 	size_t					ssid_len;
 	uint32_t				arp_addr_list[IEEE80211_BSS_ARP_ADDR_LIST_LEN];		/* big endian */
 	uint8_t					ssid[IEEE80211_NWID_LEN];
 	uint8_t					ap_addr[ETH_ALEN];
 };
 
 struct ieee80211_vif {
 	/* TODO FIXME */
 	enum nl80211_iftype		type;
 	int		csa_active, mu_mimo_owner;
 	int		cab_queue;
 	int     color_change_active, offload_flags;
 	enum ieee80211_vif_driver_flags	driver_flags;
 	bool				p2p;
 	bool				probe_req_reg;
 	uint8_t				addr[ETH_ALEN];
 	struct ieee80211_vif_cfg	cfg;
 	struct ieee80211_chanctx_conf	*chanctx_conf;
 	struct ieee80211_txq		*txq;
 	struct ieee80211_bss_conf	bss_conf;
 	struct ieee80211_bss_conf	*link_conf[IEEE80211_MLD_MAX_NUM_LINKS];	/* rcu? */
 	uint8_t				hw_queue[IEEE80211_NUM_ACS];
 	uint16_t			active_links;
 	uint16_t			valid_links;
 	struct ieee80211_vif		*mbssid_tx_vif;
 
 /* #ifdef CONFIG_MAC80211_DEBUGFS */	/* Do not change structure depending on compile-time option. */
 	struct dentry			*debugfs_dir;
 /* #endif */
 
 	/* Must stay last. */
 	uint8_t				drv_priv[0] __aligned(CACHE_LINE_SIZE);
 };
 
 struct ieee80211_vif_chanctx_switch {
 	struct ieee80211_chanctx_conf	*old_ctx, *new_ctx;
 	struct ieee80211_vif		*vif;
 	struct ieee80211_bss_conf	*link_conf;
 };
 
 struct ieee80211_prep_tx_info {
 	u16				duration;
 	bool				success;
 };
 
 /* XXX-BZ too big, over-reduce size to u8, and array sizes to minuimum to fit in skb->cb. */
 /* Also warning: some sizes change by pointer size!  This is 64bit only. */
 struct ieee80211_tx_info {
 	enum ieee80211_tx_info_flags		flags;
 	/* TODO FIXME */
 	u8		band;
 	u8		hw_queue;
 	bool		tx_time_est;
 	union {
 		struct {
 			struct ieee80211_tx_rate	rates[4];
 			bool				use_rts;
 			struct ieee80211_vif		*vif;
 			struct ieee80211_key_conf	*hw_key;
 			enum ieee80211_tx_control_flags	flags;
 		} control;
 		struct {
 			struct ieee80211_tx_rate	rates[4];
 			uint32_t			ack_signal;
 			uint8_t				ampdu_ack_len;
 			uint8_t				ampdu_len;
 			uint8_t				antenna;
 			uint16_t			tx_time;
 			uint8_t				flags;
 			void				*status_driver_data[16 / sizeof(void *)];		/* XXX TODO */
 		} status;
 #define	IEEE80211_TX_INFO_DRIVER_DATA_SIZE	40
 		void					*driver_data[IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)];
 	};
 };
 
 /* net80211 conflict */
 struct linuxkpi_ieee80211_tim_ie {
 	uint8_t				dtim_count;
 	uint8_t				dtim_period;
 	uint8_t				bitmap_ctrl;
 	uint8_t				*virtual_map;
 };
 #define	ieee80211_tim_ie	linuxkpi_ieee80211_tim_ie
 
 struct survey_info {		/* net80211::struct ieee80211_channel_survey */
 	/* TODO FIXME */
 	uint32_t			filled;
 #define	SURVEY_INFO_TIME		0x0001
 #define	SURVEY_INFO_TIME_RX		0x0002
 #define	SURVEY_INFO_TIME_SCAN		0x0004
 #define	SURVEY_INFO_TIME_TX		0x0008
 #define	SURVEY_INFO_TIME_BSS_RX		0x0010
 #define	SURVEY_INFO_TIME_BUSY		0x0020
 #define	SURVEY_INFO_IN_USE		0x0040
 #define	SURVEY_INFO_NOISE_DBM		0x0080
 	uint32_t			noise;
 	uint64_t			time;
 	uint64_t			time_bss_rx;
 	uint64_t			time_busy;
 	uint64_t			time_rx;
 	uint64_t			time_scan;
 	uint64_t			time_tx;
 	struct ieee80211_channel	*channel;
 };
 
 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 */
 	IEEE80211_IFACE_ITER_ACTIVE	= BIT(3),
 
 	/* Internal flags only. */
 	IEEE80211_IFACE_ITER__ATOMIC	= BIT(6),
 	IEEE80211_IFACE_ITER__MTX	= BIT(8),
 };
 
 enum set_key_cmd {
 	SET_KEY,
 	DISABLE_KEY,
 };
 
 /* 802.11-2020, 9.4.2.55.2 HT Capability Information field. */
 enum rx_enc_flags {
 	RX_ENC_FLAG_SHORTPRE	=	BIT(0),
 	RX_ENC_FLAG_SHORT_GI	=	BIT(2),
 	RX_ENC_FLAG_HT_GF	=	BIT(3),
 	RX_ENC_FLAG_STBC_MASK	=	BIT(4) | BIT(5),
 #define	RX_ENC_FLAG_STBC_SHIFT		4
 	RX_ENC_FLAG_LDPC	=	BIT(6),
 	RX_ENC_FLAG_BF		=	BIT(7),
 };
 
 enum sta_notify_cmd {
 	STA_NOTIFY_AWAKE,
 	STA_NOTIFY_SLEEP,
 };
 
 struct ieee80211_low_level_stats {
 	/* Can we make them uint64_t? */
 	uint32_t dot11ACKFailureCount;
 	uint32_t dot11FCSErrorCount;
 	uint32_t dot11RTSFailureCount;
 	uint32_t dot11RTSSuccessCount;
 };
 
 enum ieee80211_offload_flags {
 	IEEE80211_OFFLOAD_ENCAP_4ADDR,
 	IEEE80211_OFFLOAD_ENCAP_ENABLED,
 	IEEE80211_OFFLOAD_DECAP_ENABLED,
 };
 
 struct ieee80211_ops {
 	/* TODO FIXME */
 	int  (*start)(struct ieee80211_hw *);
 	void (*stop)(struct ieee80211_hw *);
 
 	int  (*config)(struct ieee80211_hw *, u32);
 	void (*reconfig_complete)(struct ieee80211_hw *, enum ieee80211_reconfig_type);
 
 	int  (*add_interface)(struct ieee80211_hw *, struct ieee80211_vif *);
 	void (*remove_interface)(struct ieee80211_hw *, struct ieee80211_vif *);
 	int  (*change_interface)(struct ieee80211_hw *, struct ieee80211_vif *, enum nl80211_iftype, bool);
 
 	void (*sw_scan_start)(struct ieee80211_hw *, struct ieee80211_vif *, const u8 *);
 	void (*sw_scan_complete)(struct ieee80211_hw *, struct ieee80211_vif *);
 	int  (*sched_scan_start)(struct ieee80211_hw *, struct ieee80211_vif *, struct cfg80211_sched_scan_request *, struct ieee80211_scan_ies *);
 	int  (*sched_scan_stop)(struct ieee80211_hw *, struct ieee80211_vif *);
 	int  (*hw_scan)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_scan_request *);
 	void (*cancel_hw_scan)(struct ieee80211_hw *, struct ieee80211_vif *);
 
 	int  (*conf_tx)(struct ieee80211_hw *, struct ieee80211_vif *, u32, u16, const struct ieee80211_tx_queue_params *);
 	void (*tx)(struct ieee80211_hw *, struct ieee80211_tx_control *, struct sk_buff *);
 	int  (*tx_last_beacon)(struct ieee80211_hw *);
 	void (*wake_tx_queue)(struct ieee80211_hw *, struct ieee80211_txq *);
 
 	void (*mgd_prepare_tx)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_prep_tx_info *);
 	void (*mgd_complete_tx)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_prep_tx_info *);
 	void (*mgd_protect_tdls_discover)(struct ieee80211_hw *, struct ieee80211_vif *);
 
 	void (*flush)(struct ieee80211_hw *, struct ieee80211_vif *, u32, bool);
 	void (*flush_sta)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *);
 
 	int  (*set_frag_threshold)(struct ieee80211_hw *, u32);
 
 	void (*sync_rx_queues)(struct ieee80211_hw *);
 
 	void (*allow_buffered_frames)(struct ieee80211_hw *, struct ieee80211_sta *, u16, int, enum ieee80211_frame_release_type, bool);
 	void (*release_buffered_frames)(struct ieee80211_hw *, struct ieee80211_sta *, u16, int, enum ieee80211_frame_release_type, bool);
 
 	int  (*sta_add)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *);
 	int  (*sta_remove)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *);
 	int  (*sta_set_txpwr)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *);
 	void (*sta_statistics)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, struct station_info *);
 	void (*sta_pre_rcu_remove)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *);
 	int  (*sta_state)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, enum ieee80211_sta_state, enum ieee80211_sta_state);
 	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);
 	void (*sta_set_decap_offload)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, bool);
 
 	u64  (*prepare_multicast)(struct ieee80211_hw *, struct netdev_hw_addr_list *);
 
 	int  (*ampdu_action)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_ampdu_params *);
 
 	bool (*can_aggregate_in_amsdu)(struct ieee80211_hw *, struct sk_buff *, struct sk_buff *);
 
 	int  (*pre_channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_channel_switch *);
 	int  (*post_channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *);
 	void (*channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_channel_switch *);
 	void (*channel_switch_beacon)(struct ieee80211_hw *, struct ieee80211_vif *, struct cfg80211_chan_def *);
 	void (*abort_channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *);
 	void (*channel_switch_rx_beacon)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_channel_switch *);
 	int  (*tdls_channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, u8, struct cfg80211_chan_def *, struct sk_buff *, u32);
 	void (*tdls_cancel_channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *);
 	void (*tdls_recv_channel_switch)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_tdls_ch_sw_params *);
 
 	int  (*add_chanctx)(struct ieee80211_hw *, struct ieee80211_chanctx_conf *);
 	void (*remove_chanctx)(struct ieee80211_hw *, struct ieee80211_chanctx_conf *);
 	void (*change_chanctx)(struct ieee80211_hw *, struct ieee80211_chanctx_conf *, u32);
 	int  (*assign_vif_chanctx)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *, struct ieee80211_chanctx_conf *);
 	void (*unassign_vif_chanctx)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *, struct ieee80211_chanctx_conf *);
 	int  (*switch_vif_chanctx)(struct ieee80211_hw *, struct ieee80211_vif_chanctx_switch *, int, enum ieee80211_chanctx_switch_mode);
 
 	int  (*get_antenna)(struct ieee80211_hw *, u32 *, u32 *);
 	int  (*set_antenna)(struct ieee80211_hw *, u32, u32);
 
 	int  (*remain_on_channel)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_channel *, int, enum ieee80211_roc_type);
 	int  (*cancel_remain_on_channel)(struct ieee80211_hw *, struct ieee80211_vif *);
 
 	void (*configure_filter)(struct ieee80211_hw *, unsigned int, unsigned int *, u64);
 	void (*config_iface_filter)(struct ieee80211_hw *, struct ieee80211_vif *, unsigned int, unsigned int);
 
 	void (*bss_info_changed)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *, u64);
         void (*link_info_changed)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *, u64);
 
 	int  (*set_rts_threshold)(struct ieee80211_hw *, u32);
 	void (*event_callback)(struct ieee80211_hw *, struct ieee80211_vif *, const struct ieee80211_event *);
 	int  (*get_survey)(struct ieee80211_hw *, int, struct survey_info *);
 	int  (*get_ftm_responder_stats)(struct ieee80211_hw *, struct ieee80211_vif *, struct cfg80211_ftm_responder_stats *);
 
         uint64_t (*get_tsf)(struct ieee80211_hw *, struct ieee80211_vif *);
         void (*set_tsf)(struct ieee80211_hw *, struct ieee80211_vif *, uint64_t);
 	void (*offset_tsf)(struct ieee80211_hw *, struct ieee80211_vif *, s64);
 
 	int  (*set_bitrate_mask)(struct ieee80211_hw *, struct ieee80211_vif *, const struct cfg80211_bitrate_mask *);
 	void (*set_coverage_class)(struct ieee80211_hw *, s16);
 	int  (*set_tim)(struct ieee80211_hw *, struct ieee80211_sta *, bool);
 
 	int  (*set_key)(struct ieee80211_hw *, enum set_key_cmd, struct ieee80211_vif *, struct ieee80211_sta *, struct ieee80211_key_conf *);
 	void (*set_default_unicast_key)(struct ieee80211_hw *, struct ieee80211_vif *, int);
 	void (*update_tkip_key)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_key_conf *, struct ieee80211_sta *, u32, u16 *);
 	void (*set_rekey_data)(struct ieee80211_hw *, struct ieee80211_vif *, struct cfg80211_gtk_rekey_data *);
 
 	int  (*start_pmsr)(struct ieee80211_hw *, struct ieee80211_vif *, struct cfg80211_pmsr_request *);
 	void (*abort_pmsr)(struct ieee80211_hw *, struct ieee80211_vif *, struct cfg80211_pmsr_request *);
 
 	int  (*start_ap)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *link_conf);
 	void (*stop_ap)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_bss_conf *link_conf);
 	int  (*join_ibss)(struct ieee80211_hw *, struct ieee80211_vif *);
 	void (*leave_ibss)(struct ieee80211_hw *, struct ieee80211_vif *);
 
 	int  (*set_sar_specs)(struct ieee80211_hw *, const struct cfg80211_sar_specs *);
 
 	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 *);
 
 	int  (*get_txpower)(struct ieee80211_hw *, struct ieee80211_vif *, int *);
 	int  (*get_stats)(struct ieee80211_hw *, struct ieee80211_low_level_stats *);
 
 	int  (*set_radar_background)(struct ieee80211_hw *, struct cfg80211_chan_def *);
 
 	void (*add_twt_setup)(struct ieee80211_hw *, struct ieee80211_sta *, struct ieee80211_twt_setup *);
 	void (*twt_teardown_request)(struct ieee80211_hw *, struct ieee80211_sta *, u8);
 
 	int (*set_hw_timestamp)(struct ieee80211_hw *, struct ieee80211_vif *, struct cfg80211_set_hw_timestamp *);
 
         void (*vif_cfg_changed)(struct ieee80211_hw *, struct ieee80211_vif *, u64);
 
 	int (*change_vif_links)(struct ieee80211_hw *, struct ieee80211_vif *, u16, u16, struct ieee80211_bss_conf *[IEEE80211_MLD_MAX_NUM_LINKS]);
 	int (*change_sta_links)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, u16, u16);
 
 /* #ifdef CONFIG_MAC80211_DEBUGFS */	/* Do not change depending on compile-time option. */
 	void (*sta_add_debugfs)(struct ieee80211_hw *, struct ieee80211_vif *, struct ieee80211_sta *, struct dentry *);
 /* #endif */
 };
 
 
 /* -------------------------------------------------------------------------- */
 
 /* linux_80211.c */
 extern const struct cfg80211_ops linuxkpi_mac80211cfgops;
 
 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 *);
 int linuxkpi_ieee80211_ifattach(struct ieee80211_hw *);
 void linuxkpi_ieee80211_ifdetach(struct ieee80211_hw *);
 void linuxkpi_ieee80211_unregister_hw(struct ieee80211_hw *);
 struct ieee80211_hw * linuxkpi_wiphy_to_ieee80211_hw(struct wiphy *);
 void linuxkpi_ieee80211_restart_hw(struct ieee80211_hw *);
 void linuxkpi_ieee80211_iterate_interfaces(
     struct ieee80211_hw *hw, enum ieee80211_iface_iter flags,
     void(*iterfunc)(void *, uint8_t *, struct ieee80211_vif *),
     void *);
 void linuxkpi_ieee80211_iterate_keys(struct ieee80211_hw *,
     struct ieee80211_vif *,
     void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_vif *,
         struct ieee80211_sta *, struct ieee80211_key_conf *, void *),
     void *);
 void linuxkpi_ieee80211_iterate_chan_contexts(struct ieee80211_hw *,
     void(*iterfunc)(struct ieee80211_hw *,
 	struct ieee80211_chanctx_conf *, void *),
     void *);
 void linuxkpi_ieee80211_iterate_stations_atomic(struct ieee80211_hw *,
    void (*iterfunc)(void *, struct ieee80211_sta *), void *);
 void linuxkpi_ieee80211_scan_completed(struct ieee80211_hw *,
     struct cfg80211_scan_info *);
 void linuxkpi_ieee80211_rx(struct ieee80211_hw *, struct sk_buff *,
     struct ieee80211_sta *, struct napi_struct *, struct list_head *);
 uint8_t linuxkpi_ieee80211_get_tid(struct ieee80211_hdr *, bool);
 struct ieee80211_sta *linuxkpi_ieee80211_find_sta(struct ieee80211_vif *,
     const u8 *);
 struct ieee80211_sta *linuxkpi_ieee80211_find_sta_by_ifaddr(
     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);
 bool linuxkpi_ieee80211_ie_advance(size_t *, const u8 *, size_t);
 void linuxkpi_ieee80211_free_txskb(struct ieee80211_hw *, struct sk_buff *,
     int);
 void linuxkpi_ieee80211_queue_delayed_work(struct ieee80211_hw *,
     struct delayed_work *, int);
 void linuxkpi_ieee80211_queue_work(struct ieee80211_hw *, struct work_struct *);
 struct sk_buff *linuxkpi_ieee80211_pspoll_get(struct ieee80211_hw *,
     struct ieee80211_vif *);
 struct sk_buff *linuxkpi_ieee80211_nullfunc_get(struct ieee80211_hw *,
     struct ieee80211_vif *, int, bool);
 void linuxkpi_ieee80211_txq_get_depth(struct ieee80211_txq *, unsigned long *,
     unsigned long *);
 struct wireless_dev *linuxkpi_ieee80211_vif_to_wdev(struct ieee80211_vif *);
 void linuxkpi_ieee80211_connection_loss(struct ieee80211_vif *);
 void linuxkpi_ieee80211_beacon_loss(struct ieee80211_vif *);
 struct sk_buff *linuxkpi_ieee80211_probereq_get(struct ieee80211_hw *,
     uint8_t *, uint8_t *, size_t, size_t);
 void linuxkpi_ieee80211_tx_status(struct ieee80211_hw *, struct sk_buff *);
 void linuxkpi_ieee80211_tx_status_ext(struct ieee80211_hw *,
     struct ieee80211_tx_status *);
 void linuxkpi_ieee80211_stop_queues(struct ieee80211_hw *);
 void linuxkpi_ieee80211_wake_queues(struct ieee80211_hw *);
 void linuxkpi_ieee80211_stop_queue(struct ieee80211_hw *, int);
 void linuxkpi_ieee80211_wake_queue(struct ieee80211_hw *, int);
 void linuxkpi_ieee80211_txq_schedule_start(struct ieee80211_hw *, uint8_t);
 struct ieee80211_txq *linuxkpi_ieee80211_next_txq(struct ieee80211_hw *, uint8_t);
 void linuxkpi_ieee80211_schedule_txq(struct ieee80211_hw *,
     struct ieee80211_txq *, bool);
 void linuxkpi_ieee80211_handle_wake_tx_queue(struct ieee80211_hw *,
 	struct ieee80211_txq *);
 
 /* -------------------------------------------------------------------------- */
 
 static __inline void
 _ieee80211_hw_set(struct ieee80211_hw *hw, enum ieee80211_hw_flags flag)
 {
 
 	set_bit(flag, hw->flags);
 }
 
 static __inline bool
 __ieee80211_hw_check(struct ieee80211_hw *hw, enum ieee80211_hw_flags flag)
 {
 
 	return (test_bit(flag, hw->flags));
 }
 
 /* They pass in shortened flag names; how confusingly inconsistent. */
 #define	ieee80211_hw_set(_hw, _flag)					\
 	_ieee80211_hw_set(_hw, IEEE80211_HW_ ## _flag)
 #define	ieee80211_hw_check(_hw, _flag)					\
 	__ieee80211_hw_check(_hw, IEEE80211_HW_ ## _flag)
 
 /* XXX-BZ add CTASSERTS that size of struct is <= sizeof skb->cb. */
 CTASSERT(sizeof(struct ieee80211_tx_info) <= sizeof(((struct sk_buff *)0)->cb));
 #define	IEEE80211_SKB_CB(_skb)						\
 	((struct ieee80211_tx_info *)((_skb)->cb))
 
 CTASSERT(sizeof(struct ieee80211_rx_status) <= sizeof(((struct sk_buff *)0)->cb));
 #define	IEEE80211_SKB_RXCB(_skb)					\
 	((struct ieee80211_rx_status *)((_skb)->cb))
 
 static __inline void
 ieee80211_free_hw(struct ieee80211_hw *hw)
 {
 
 	linuxkpi_ieee80211_iffree(hw);
 
 	if (hw->wiphy != NULL)
 		wiphy_free(hw->wiphy);
 	/* Note that *hw is not valid any longer after this. */
 
 	IMPROVE();
 }
 
 static __inline struct ieee80211_hw *
 ieee80211_alloc_hw(size_t priv_len, const struct ieee80211_ops *ops)
 {
 
 	return (linuxkpi_ieee80211_alloc_hw(priv_len, ops));
 }
 
 static __inline void
 SET_IEEE80211_DEV(struct ieee80211_hw *hw, struct device *dev)
 {
 
 	set_wiphy_dev(hw->wiphy, dev);
 	linuxkpi_set_ieee80211_dev(hw, dev_name(dev));
 
 	IMPROVE();
 }
 
 static __inline int
 ieee80211_register_hw(struct ieee80211_hw *hw)
 {
 	int error;
 
 	error = wiphy_register(hw->wiphy);
 	if (error != 0)
 		return (error);
 
 	/*
 	 * At this point the driver has set all the options, flags, bands,
 	 * ciphers, hw address(es), ... basically mac80211/cfg80211 hw/wiphy
 	 * setup is done.
 	 * We need to replicate a lot of information from here into net80211.
 	 */
 	error = linuxkpi_ieee80211_ifattach(hw);
 
 	IMPROVE();
 
 	return (error);
 }
 
 static inline void
 ieee80211_unregister_hw(struct ieee80211_hw *hw)
 {
 
 	linuxkpi_ieee80211_unregister_hw(hw);
 }
 
 static __inline struct ieee80211_hw *
 wiphy_to_ieee80211_hw(struct wiphy *wiphy)
 {
 
 	return (linuxkpi_wiphy_to_ieee80211_hw(wiphy));
 }
 
 static inline void
 ieee80211_restart_hw(struct ieee80211_hw *hw)
 {
 	linuxkpi_ieee80211_restart_hw(hw);
 }
 
 static inline void
 ieee80211_hw_restart_disconnect(struct ieee80211_vif *vif)
 {
 	TODO();
 }
 
 /* -------------------------------------------------------------------------- */
 
 #define	link_conf_dereference_check(_vif, _linkid)			\
     rcu_dereference_check((_vif)->link_conf[_linkid], true)
 
 #define	link_conf_dereference_protected(_vif, _linkid)			\
     rcu_dereference_protected((_vif)->link_conf[_linkid], true)
 
 #define	link_sta_dereference_check(_sta, _linkid)			\
     rcu_dereference_check((_sta)->link[_linkid], true)
 
 #define	link_sta_dereference_protected(_sta, _linkid)			\
     rcu_dereference_protected((_sta)->link[_linkid], true)
 
 #define	for_each_vif_active_link(_vif, _link, _linkid)			\
     for (_linkid = 0; _linkid < nitems((_vif)->link_conf); _linkid++)	\
 	if ( ((_vif)->active_links == 0 /* no MLO */ ||			\
 	    ((_vif)->active_links & BIT(_linkid)) != 0) &&		\
 	    (_link = rcu_dereference((_vif)->link_conf[_linkid])) )
 
 #define	for_each_sta_active_link(_vif, _sta, _linksta, _linkid)		\
     for (_linkid = 0; _linkid < nitems((_sta)->link); _linkid++)	\
 	if ( ((_vif)->active_links == 0 /* no MLO */ ||			\
 	    ((_vif)->active_links & BIT(_linkid)) != 0) &&		\
 	    (_linksta = link_sta_dereference_protected((_sta), (_linkid))) )
 
 /* -------------------------------------------------------------------------- */
 
 static __inline bool
 ieee80211_is_action(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_ACTION | IEEE80211_FC0_TYPE_MGT);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_is_probe_resp(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_PROBE_RESP | IEEE80211_FC0_TYPE_MGT);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_is_auth(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_AUTH | IEEE80211_FC0_TYPE_MGT);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_is_assoc_req(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_ASSOC_REQ | IEEE80211_FC0_TYPE_MGT);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_is_assoc_resp(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_ASSOC_RESP | IEEE80211_FC0_TYPE_MGT);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_is_reassoc_req(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_REASSOC_REQ | IEEE80211_FC0_TYPE_MGT);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_is_reassoc_resp(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_REASSOC_RESP | IEEE80211_FC0_TYPE_MGT);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_is_disassoc(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_DISASSOC | IEEE80211_FC0_TYPE_MGT);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_is_data_present(__le16 fc)
 {
 	__le16 v;
 
 	/* If it is a data frame and NODATA is not present. */
 	fc &= htole16(IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_NODATA);
 	v = htole16(IEEE80211_FC0_TYPE_DATA);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_is_deauth(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_DEAUTH | IEEE80211_FC0_TYPE_MGT);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_is_beacon(__le16 fc)
 {
 	__le16 v;
 
 	/*
 	 * For as much as I get it this comes in LE and unlike FreeBSD
 	 * where we get the entire frame header and u8[], here we get the
 	 * 9.2.4.1 Frame Control field only. Mask and compare.
 	 */
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_BEACON | IEEE80211_FC0_TYPE_MGT);
 
 	return (fc == v);
 }
 
 
 static __inline bool
 ieee80211_is_probe_req(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_PROBE_REQ | IEEE80211_FC0_TYPE_MGT);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_has_protected(__le16 fc)
 {
 
 	return (fc & htole16(IEEE80211_FC1_PROTECTED << 8));
 }
 
 static __inline bool
 ieee80211_is_back_req(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_BAR | IEEE80211_FC0_TYPE_CTL);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_is_bufferable_mmpdu(struct sk_buff *skb)
 {
 	struct ieee80211_mgmt *mgmt;
 	__le16 fc;
 
 	mgmt = (struct ieee80211_mgmt *)skb->data;
 	fc = mgmt->frame_control;
 
 	/* 11.2.2 Bufferable MMPDUs, 80211-2020. */
 	/* XXX we do not care about IBSS yet. */
 
 	if (!ieee80211_is_mgmt(fc))
 		return (false);
 	if (ieee80211_is_action(fc))		/* XXX FTM? */
 		return (true);			/* XXX false? */
 	if (ieee80211_is_disassoc(fc))
 		return (true);
 	if (ieee80211_is_deauth(fc))
 		return (true);
 
 	TODO();
 
 	return (false);
 }
 
 static __inline bool
 ieee80211_is_nullfunc(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_NODATA | IEEE80211_FC0_TYPE_DATA);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_is_qos_nullfunc(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_QOS_NULL | IEEE80211_FC0_TYPE_DATA);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_is_any_nullfunc(__le16 fc)
 {
 
 	return (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc));
 }
 
 static inline bool
 ieee80211_is_pspoll(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16(IEEE80211_FC0_SUBTYPE_MASK | IEEE80211_FC0_TYPE_MASK);
 	v = htole16(IEEE80211_FC0_SUBTYPE_PS_POLL | IEEE80211_FC0_TYPE_CTL);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_vif_is_mesh(struct ieee80211_vif *vif)
 {
 	TODO();
 	return (false);
 }
 
 static __inline bool
 ieee80211_is_frag(struct ieee80211_hdr *hdr)
 {
 	TODO();
 	return (false);
 }
 
 static __inline bool
 ieee80211_is_first_frag(__le16 fc)
 {
 	TODO();
 	return (false);
 }
 
 static __inline bool
 ieee80211_is_robust_mgmt_frame(struct sk_buff *skb)
 {
 	TODO();
 	return (false);
 }
 
 static __inline bool
 ieee80211_is_ftm(struct sk_buff *skb)
 {
 	TODO();
 	return (false);
 }
 
 static __inline bool
 ieee80211_is_timing_measurement(struct sk_buff *skb)
 {
 	TODO();
 	return (false);
 }
 
 static __inline bool
 ieee80211_has_pm(__le16 fc)
 {
 	TODO();
 	return (false);
 }
 
 static __inline bool
 ieee80211_has_a4(__le16 fc)
 {
 	__le16 v;
 
 	fc &= htole16((IEEE80211_FC1_DIR_TODS | IEEE80211_FC1_DIR_FROMDS) << 8);
 	v = htole16((IEEE80211_FC1_DIR_TODS | IEEE80211_FC1_DIR_FROMDS) << 8);
 
 	return (fc == v);
 }
 
 static __inline bool
 ieee80211_has_order(__le16 fc)
 {
 
 	return (fc & htole16(IEEE80211_FC1_ORDER << 8));
 }
 
 static __inline bool
 ieee80211_has_retry(__le16 fc)
 {
 
 	return (fc & htole16(IEEE80211_FC1_RETRY << 8));
 }
 
 
 static __inline bool
 ieee80211_has_fromds(__le16 fc)
 {
 
 	return (fc & htole16(IEEE80211_FC1_DIR_FROMDS << 8));
 }
 
 static __inline bool
 ieee80211_has_tods(__le16 fc)
 {
 
 	return (fc & htole16(IEEE80211_FC1_DIR_TODS << 8));
 }
 
 static __inline uint8_t *
 ieee80211_get_SA(struct ieee80211_hdr *hdr)
 {
 
 	if (ieee80211_has_a4(hdr->frame_control))
 		return (hdr->addr4);
 	if (ieee80211_has_fromds(hdr->frame_control))
 		return (hdr->addr3);
 	return (hdr->addr2);
 }
 
 static __inline uint8_t *
 ieee80211_get_DA(struct ieee80211_hdr *hdr)
 {
 
 	if (ieee80211_has_tods(hdr->frame_control))
 		return (hdr->addr3);
 	return (hdr->addr1);
 }
 
 static __inline bool
 ieee80211_has_morefrags(__le16 fc)
 {
 
 	fc &= htole16(IEEE80211_FC1_MORE_FRAG << 8);
 	return (fc != 0);
 }
 
 static __inline u8 *
 ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr)
 {
         if (ieee80211_has_a4(hdr->frame_control))
                 return (u8 *)hdr + 30;
         else
                 return (u8 *)hdr + 24;
 }
 
 /* -------------------------------------------------------------------------- */
 /* Receive functions (air/driver to mac80211/net80211). */
 
 
 static __inline void
 ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
     struct sk_buff *skb, struct napi_struct *napi)
 {
 
 	linuxkpi_ieee80211_rx(hw, skb, sta, napi, NULL);
 }
 
 static __inline void
 ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
     struct sk_buff *skb, struct list_head *list)
 {
 
 	linuxkpi_ieee80211_rx(hw, skb, sta, NULL, list);
 }
 
 static __inline void
 ieee80211_rx_ni(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 
 	linuxkpi_ieee80211_rx(hw, skb, NULL, NULL, NULL);
 }
 
 static __inline void
 ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 
 	linuxkpi_ieee80211_rx(hw, skb, NULL, NULL, NULL);
 }
 
 static __inline void
 ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 
 	linuxkpi_ieee80211_rx(hw, skb, NULL, NULL, NULL);
 }
 
 /* -------------------------------------------------------------------------- */
 
 static inline void
 ieee80211_stop_queues(struct ieee80211_hw *hw)
 {
 	linuxkpi_ieee80211_stop_queues(hw);
 }
 
 static inline void
 ieee80211_wake_queues(struct ieee80211_hw *hw)
 {
 	linuxkpi_ieee80211_wake_queues(hw);
 }
 
 static inline void
 ieee80211_stop_queue(struct ieee80211_hw *hw, int qnum)
 {
 	linuxkpi_ieee80211_stop_queue(hw, qnum);
 }
 
 static inline void
 ieee80211_wake_queue(struct ieee80211_hw *hw, int qnum)
 {
 	linuxkpi_ieee80211_wake_queue(hw, qnum);
 }
 
 static inline void
 ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
 {
 	linuxkpi_ieee80211_schedule_txq(hw, txq, true);
 }
 
 static inline void
 ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq,
     bool withoutpkts)
 {
 	linuxkpi_ieee80211_schedule_txq(hw, txq, withoutpkts);
 }
 
 static inline void
 ieee80211_txq_schedule_start(struct ieee80211_hw *hw, uint8_t ac)
 {
 	linuxkpi_ieee80211_txq_schedule_start(hw, ac);
 }
 
 static inline void
 ieee80211_txq_schedule_end(struct ieee80211_hw *hw, uint8_t ac)
 {
 	/* DO_NADA; */
 }
 
 static inline struct ieee80211_txq *
 ieee80211_next_txq(struct ieee80211_hw *hw, uint8_t ac)
 {
 	return (linuxkpi_ieee80211_next_txq(hw, ac));
 }
 
 static inline void
 ieee80211_handle_wake_tx_queue(struct ieee80211_hw *hw,
     struct ieee80211_txq *txq)
 {
 	linuxkpi_ieee80211_handle_wake_tx_queue(hw, txq);
 }
 
 /* -------------------------------------------------------------------------- */
 
 static __inline uint8_t
 ieee80211_get_tid(struct ieee80211_hdr *hdr)
 {
 
 	return (linuxkpi_ieee80211_get_tid(hdr, false));
 }
 
 static __inline struct sk_buff *
 ieee80211_beacon_get_tim(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
     uint16_t *tim_offset, uint16_t *tim_len, uint32_t link_id)
 {
 
 	if (tim_offset != NULL)
 		*tim_offset = 0;
 	if (tim_len != NULL)
 		*tim_len = 0;
 	TODO();
 	return (NULL);
 }
 
 static __inline void
 ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw,
     enum ieee80211_iface_iter flags,
     void(*iterfunc)(void *, uint8_t *, struct ieee80211_vif *),
     void *arg)
 {
 
 	flags |= IEEE80211_IFACE_ITER__ATOMIC;
 	flags |= IEEE80211_IFACE_ITER_ACTIVE;
 	linuxkpi_ieee80211_iterate_interfaces(hw, flags, iterfunc, arg);
 }
 
 static __inline void
 ieee80211_iterate_active_interfaces(struct ieee80211_hw *hw,
     enum ieee80211_iface_iter flags,
     void(*iterfunc)(void *, uint8_t *, struct ieee80211_vif *),
     void *arg)
 {
 
 	flags |= IEEE80211_IFACE_ITER_ACTIVE;
 	linuxkpi_ieee80211_iterate_interfaces(hw, flags, iterfunc, arg);
 }
 
 static __inline void
 ieee80211_iterate_active_interfaces_mtx(struct ieee80211_hw *hw,
     enum ieee80211_iface_iter flags,
     void(*iterfunc)(void *, uint8_t *, struct ieee80211_vif *),
     void *arg)
 {
 	flags |= IEEE80211_IFACE_ITER_ACTIVE;
 	flags |= IEEE80211_IFACE_ITER__MTX;
 	linuxkpi_ieee80211_iterate_interfaces(hw, flags, iterfunc, arg);
 }
 
 static __inline void
 ieee80211_iterate_interfaces(struct ieee80211_hw *hw,
    enum ieee80211_iface_iter flags,
    void (*iterfunc)(void *, uint8_t *, struct ieee80211_vif *),
    void *arg)
 {
 
 	linuxkpi_ieee80211_iterate_interfaces(hw, flags, iterfunc, arg);
 }
 
 static __inline void
 ieee80211_iter_keys(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
     void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_vif *,
         struct ieee80211_sta *, struct ieee80211_key_conf *, void *),
     void *arg)
 {
 
 	linuxkpi_ieee80211_iterate_keys(hw, vif, iterfunc, arg);
 }
 
 static __inline void
 ieee80211_iter_keys_rcu(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
     void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_vif *,
         struct ieee80211_sta *, struct ieee80211_key_conf *, void *),
     void *arg)
 {
 
 	IMPROVE();	/* "rcu" */
 	linuxkpi_ieee80211_iterate_keys(hw, vif, iterfunc, arg);
 }
 
 static __inline void
 ieee80211_iter_chan_contexts_atomic(struct ieee80211_hw *hw,
     void(*iterfunc)(struct ieee80211_hw *, struct ieee80211_chanctx_conf *, void *),
     void *arg)
 {
 
 	linuxkpi_ieee80211_iterate_chan_contexts(hw, iterfunc, arg);
 }
 
 static __inline void
 ieee80211_iterate_stations_atomic(struct ieee80211_hw *hw,
    void (*iterfunc)(void *, struct ieee80211_sta *), void *arg)
 {
 
 	linuxkpi_ieee80211_iterate_stations_atomic(hw, iterfunc, arg);
 }
 
 static __inline struct wireless_dev *
 ieee80211_vif_to_wdev(struct ieee80211_vif *vif)
 {
 
 	return (linuxkpi_ieee80211_vif_to_wdev(vif));
 }
 
 static __inline struct sk_buff *
 ieee80211_beacon_get_template(struct ieee80211_hw *hw,
     struct ieee80211_vif *vif, struct ieee80211_mutable_offsets *offs,
     uint32_t link_id)
 {
 	TODO();
 	return (NULL);
 }
 
 static __inline void
 ieee80211_beacon_loss(struct ieee80211_vif *vif)
 {
 	linuxkpi_ieee80211_beacon_loss(vif);
 }
 
 static __inline void
 ieee80211_chswitch_done(struct ieee80211_vif *vif, bool t)
 {
 	TODO();
 }
 
 static __inline bool
 ieee80211_csa_is_complete(struct ieee80211_vif *vif)
 {
 	TODO();
 	return (false);
 }
 
 static __inline void
 ieee80211_csa_set_counter(struct ieee80211_vif *vif, uint8_t counter)
 {
 	TODO();
 }
 
 static __inline int
 ieee80211_csa_update_counter(struct ieee80211_vif *vif)
 {
 	TODO();
 	return (-1);
 }
 
 static __inline void
 ieee80211_csa_finish(struct ieee80211_vif *vif)
 {
 	TODO();
 }
 
 static __inline enum nl80211_iftype
 ieee80211_vif_type_p2p(struct ieee80211_vif *vif)
 {
 
 	/* If we are not p2p enabled, just return the type. */
 	if (!vif->p2p)
 		return (vif->type);
 
 	/* If we are p2p, depending on side, return type. */
 	switch (vif->type) {
 	case NL80211_IFTYPE_AP:
 		return (NL80211_IFTYPE_P2P_GO);
 	case NL80211_IFTYPE_STATION:
 		return (NL80211_IFTYPE_P2P_CLIENT);
 	default:
 		fallthrough;
 	}
 	return (vif->type);
 }
 
 static __inline unsigned long
 ieee80211_tu_to_usec(unsigned long tu)
 {
 
 	return (tu * IEEE80211_DUR_TU);
 }
 
 /*
  * Below we assume that the two values from different emums are the same.
  * Make sure this does not accidentally change.
  */
 CTASSERT((int)IEEE80211_ACTION_SM_TPCREP == (int)IEEE80211_ACTION_RADIO_MEASUREMENT_LMREP);
 
 static __inline bool
 ieee80211_action_contains_tpc(struct sk_buff *skb)
 {
 	struct ieee80211_mgmt *mgmt;
 
 	mgmt = (struct ieee80211_mgmt *)skb->data;
 
 	/* Check that this is a mgmt/action frame? */
 	if (!ieee80211_is_action(mgmt->frame_control))
 		return (false);
 
 	/*
 	 * This is a bit convoluted but according to docs both actions
 	 * are checked for this.  Kind-of makes sense for the only consumer
 	 * (iwlwifi) I am aware off given the txpower fields are at the
 	 * same location so firmware can update the value.
 	 */
 	/* 80211-2020 9.6.2 Spectrum Management Action frames */
 	/* 80211-2020 9.6.2.5 TPC Report frame format */
 	/* 80211-2020 9.6.6 Radio Measurement action details */
 	/* 80211-2020 9.6.6.4 Link Measurement Report frame format */
 	/* Check that it is Spectrum Management or Radio Measurement? */
 	if (mgmt->u.action.category != IEEE80211_ACTION_CAT_SM &&
 	    mgmt->u.action.category != IEEE80211_ACTION_CAT_RADIO_MEASUREMENT)
 		return (false);
 
 	/*
 	 * Check that it is TPC Report or Link Measurement Report?
 	 * The values of each are the same (see CTASSERT above function).
 	 */
 	if (mgmt->u.action.u.tpc_report.spec_mgmt != IEEE80211_ACTION_SM_TPCREP)
 		return (false);
 
 	/* 80211-2020 9.4.2.16 TPC Report element */
 	/* Check that the ELEMID and length are correct? */
 	if (mgmt->u.action.u.tpc_report.tpc_elem_id != IEEE80211_ELEMID_TPCREP ||
 	    mgmt->u.action.u.tpc_report.tpc_elem_length != 4)
 		return (false);
 
 	/* All the right fields in the right place. */
 	return (true);
 }
 
 static __inline void
 ieee80211_connection_loss(struct ieee80211_vif *vif)
 {
 
 	linuxkpi_ieee80211_connection_loss(vif);
 }
 
 static __inline struct ieee80211_sta *
 ieee80211_find_sta(struct ieee80211_vif *vif, const u8 *peer)
 {
 
 	return (linuxkpi_ieee80211_find_sta(vif, peer));
 }
 
 static __inline struct ieee80211_sta *
 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));
 }
 
 
 static __inline void
 ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf,
     struct sk_buff *skb_frag, u8 *key)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_get_tkip_rx_p1k(struct ieee80211_key_conf *keyconf,
     const u8 *addr, uint32_t iv32, u16 *p1k)
 {
 
 	KASSERT(keyconf != NULL && addr != NULL && p1k != NULL,
 	    ("%s: keyconf %p addr %p p1k %p\n", __func__, keyconf, addr, p1k));
 
 	TODO();
 	memset(p1k, 0xfa, 5 * sizeof(*p1k));	/* Just initializing. */
 }
 
 static __inline size_t
 ieee80211_ie_split(const u8 *ies, size_t ies_len,
     const u8 *ie_ids, size_t ie_ids_len, size_t start)
 {
 	size_t x;
 
 	x = start;
 
 	/* XXX FIXME, we need to deal with "Element ID Extension" */
 	while (x < ies_len) {
 
 		/* Is this IE[s] one of the ie_ids? */
 		if (!linuxkpi_ieee80211_is_ie_id_in_ie_buf(ies[x],
 		    ie_ids, ie_ids_len))
 			break;
 
 		if (!linuxkpi_ieee80211_ie_advance(&x, ies, ies_len))
 			break;
 	}
 
 	return (x);
 }
 
 static __inline void
 ieee80211_request_smps(struct ieee80211_vif *vif, u_int link_id,
     enum ieee80211_smps_mode smps)
 {
 	static const char *smps_mode_name[] = {
 		"SMPS_OFF",
 		"SMPS_STATIC",
 		"SMPS_DYNAMIC",
 		"SMPS_AUTOMATIC",
 		"SMPS_NUM_MODES"
 	};
 
 	if (linuxkpi_debug_80211 & D80211_TODO)
 		printf("%s:%d: XXX LKPI80211 TODO smps %d %s\n",
 		    __func__, __LINE__, smps, smps_mode_name[smps]);
 }
 
 static __inline void
 ieee80211_tdls_oper_request(struct ieee80211_vif *vif, uint8_t *addr,
     enum nl80211_tdls_operation oper, enum ieee80211_reason_code code,
     gfp_t gfp)
 {
 	TODO();
 }
 
 static __inline void
 wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool state)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 	IMPROVE();
 
 	/*
 	 * This is called on transmit failure.
 	 * Use a not-so-random random high status error so we can distinguish
 	 * it from normal low values flying around in net80211 ("ETX").
 	 */
 	linuxkpi_ieee80211_free_txskb(hw, skb, 0x455458);
 }
 
 static __inline void
 ieee80211_ready_on_channel(struct ieee80211_hw *hw)
 {
 	TODO();
 /* XXX-BZ We need to see that. */
 }
 
 static __inline void
 ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
     enum nl80211_cqm_rssi_threshold_event crte, int sig, gfp_t gfp)
 {
 	TODO();
 }
 
 /* -------------------------------------------------------------------------- */
 
 static inline bool
 ieee80211_sn_less(uint16_t sn1, uint16_t sn2)
 {
 	return (IEEE80211_SEQ_BA_BEFORE(sn1, sn2));
 }
 
 static inline uint16_t
 ieee80211_sn_inc(uint16_t sn)
 {
 	return (IEEE80211_SEQ_INC(sn));
 }
 
 static inline uint16_t
 ieee80211_sn_add(uint16_t sn, uint16_t a)
 {
 	return (IEEE80211_SEQ_ADD(sn, a));
 }
 
 static inline uint16_t
 ieee80211_sn_sub(uint16_t sa, uint16_t sb)
 {
 	return (IEEE80211_SEQ_SUB(sa, sb));
 }
 
 static __inline void
 ieee80211_mark_rx_ba_filtered_frames(struct ieee80211_sta *sta, uint8_t tid,
     uint32_t ssn, uint64_t bitmap, uint16_t received_mpdu)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, uint32_t x, uint8_t *addr)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_rx_ba_timer_expired(struct ieee80211_vif *vif, uint8_t *addr,
     uint8_t tid)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_start_rx_ba_session_offl(struct ieee80211_vif *vif, uint8_t *addr,
     uint8_t tid)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_stop_rx_ba_session_offl(struct ieee80211_vif *vif, uint8_t *addr,
     uint8_t tid)
 {
 	TODO();
 }
 
 /* -------------------------------------------------------------------------- */
 
 static __inline void
 ieee80211_rate_set_vht(struct ieee80211_tx_rate *r, uint32_t f1, uint32_t f2)
 {
 	TODO();
 }
 
 static __inline uint8_t
 ieee80211_rate_get_vht_nss(struct ieee80211_tx_rate *r)
 {
 	TODO();
 	return (0);
 }
 
 static __inline uint8_t
 ieee80211_rate_get_vht_mcs(struct ieee80211_tx_rate *r)
 {
 	TODO();
 	return (0);
 }
 
 static __inline void
 ieee80211_reserve_tid(struct ieee80211_sta *sta, uint8_t tid)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_unreserve_tid(struct ieee80211_sta *sta, uint8_t tid)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_send_eosp_nullfunc(struct ieee80211_sta *sta, uint8_t tid)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_sta_block_awake(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
     bool disable)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool sleeping)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_sta_pspoll(struct ieee80211_sta *sta)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_sta_recalc_aggregates(struct ieee80211_sta *sta)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_sta_uapsd_trigger(struct ieee80211_sta *sta, int ntids)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_tkip_add_iv(u8 *crypto_hdr, struct ieee80211_key_conf *keyconf,
     uint64_t pn)
 {
 	TODO();
 }
 
 static inline struct sk_buff *
 ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
 {
 
 	return (linuxkpi_ieee80211_tx_dequeue(hw, txq));
 }
 
 static inline struct sk_buff *
 ieee80211_tx_dequeue_ni(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
 {
 	struct sk_buff *skb;
 
 	local_bh_disable();
 	skb = linuxkpi_ieee80211_tx_dequeue(hw, txq);
 	local_bh_enable();
 
 	return (skb);
 }
 
 static __inline void
 ieee80211_update_mu_groups(struct ieee80211_vif *vif,
     u_int _i, uint8_t *ms, uint8_t *up)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_sta_set_buffered(struct ieee80211_sta *sta, uint8_t tid, bool t)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf, uint8_t tid,
     struct ieee80211_key_seq *seq)
 {
 
 	KASSERT(keyconf != NULL && seq != NULL, ("%s: keyconf %p seq %p\n",
 	    __func__, keyconf, seq));
 
 	TODO();
 	switch (keyconf->cipher) {
 	case WLAN_CIPHER_SUITE_CCMP:
 	case WLAN_CIPHER_SUITE_CCMP_256:
 		memset(seq->ccmp.pn, 0xfa, sizeof(seq->ccmp.pn));	/* XXX TODO */
 		break;
 	case WLAN_CIPHER_SUITE_AES_CMAC:
 		memset(seq->aes_cmac.pn, 0xfa, sizeof(seq->aes_cmac.pn));	/* XXX TODO */
 		break;
 	case WLAN_CIPHER_SUITE_TKIP:
 		seq->tkip.iv32 = 0xfa;		/* XXX TODO */
 		seq->tkip.iv16 = 0xfa;		/* XXX TODO */
 		break;
 	default:
 		pr_debug("%s: unsupported cipher suite %d\n", __func__, keyconf->cipher);
 		break;
 	}
 }
 
 static __inline void
 ieee80211_sched_scan_results(struct ieee80211_hw *hw)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_sta_eosp(struct ieee80211_sta *sta)
 {
 	TODO();
 }
 
 static __inline int
 ieee80211_start_tx_ba_session(struct ieee80211_sta *sta, uint8_t tid, int x)
 {
 	TODO("rtw8x");
 	return (-EINVAL);
 }
 
 static __inline int
 ieee80211_stop_tx_ba_session(struct ieee80211_sta *sta, uint8_t tid)
 {
 	TODO("rtw89");
 	return (-EINVAL);
 }
 
 static __inline void
 ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, uint8_t *addr,
     uint8_t tid)
 {
 	TODO("iwlwifi");
 }
 
 static __inline void
 ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, uint8_t *addr,
     uint8_t tid)
 {
 	TODO("iwlwifi/rtw8x/...");
 }
 
 static __inline void
 ieee80211_sched_scan_stopped(struct ieee80211_hw *hw)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_scan_completed(struct ieee80211_hw *hw,
     struct cfg80211_scan_info *info)
 {
 
 	linuxkpi_ieee80211_scan_completed(hw, info);
 }
 
 static __inline struct sk_buff *
 ieee80211_beacon_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
     uint32_t link_id)
 {
 	TODO();
 	return (NULL);
 }
 
 static __inline struct sk_buff *
 ieee80211_pspoll_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
 
 	/* Only STA needs this.  Otherwise return NULL and panic bad drivers. */
 	if (vif->type != NL80211_IFTYPE_STATION)
 		return (NULL);
 
 	return (linuxkpi_ieee80211_pspoll_get(hw, vif));
 }
 
 static __inline struct sk_buff *
 ieee80211_proberesp_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 {
 	TODO();
 	return (NULL);
 }
 
 static __inline struct sk_buff *
 ieee80211_nullfunc_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
     int linkid, bool qos)
 {
 
 	/* Only STA needs this.  Otherwise return NULL and panic bad drivers. */
 	if (vif->type != NL80211_IFTYPE_STATION)
 		return (NULL);
 
 	return (linuxkpi_ieee80211_nullfunc_get(hw, vif, linkid, qos));
 }
 
 static __inline struct sk_buff *
 ieee80211_probereq_get(struct ieee80211_hw *hw, uint8_t *addr,
     uint8_t *ssid, size_t ssid_len, size_t tailroom)
 {
 
 	return (linuxkpi_ieee80211_probereq_get(hw, addr, ssid, ssid_len,
 	    tailroom));
 }
 
 static __inline void
 ieee80211_queue_delayed_work(struct ieee80211_hw *hw, struct delayed_work *w,
     int delay)
 {
 
 	linuxkpi_ieee80211_queue_delayed_work(hw, w, delay);
 }
 
 static __inline void
 ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *w)
 {
 
 	linuxkpi_ieee80211_queue_work(hw, w);
 }
 
 static __inline void
 ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 
 	linuxkpi_ieee80211_tx_status(hw, skb);
 }
 
 static __inline void
 ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 	IMPROVE();
 	ieee80211_tx_status(hw, skb);
 }
 
 static __inline void
 ieee80211_tx_status_ni(struct ieee80211_hw *hw, struct sk_buff *skb)
 {
 	IMPROVE();
 	ieee80211_tx_status(hw, skb);
 }
 
 static __inline void
 ieee80211_tx_status_ext(struct ieee80211_hw *hw,
     struct ieee80211_tx_status *txstat)
 {
 
 	linuxkpi_ieee80211_tx_status_ext(hw, txstat);
 }
 
 static __inline void
 ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
 {
 	int i;
 
 	/*
 	 * Apparently clearing flags and some other fields is not right.
 	 * Given the function is called "status" we work on that part of
 	 * the union.
 	 */
 	for (i = 0; i < nitems(info->status.rates); i++)
 		info->status.rates[i].count = 0;
 	/*
 	 * Unclear if ack_signal should be included or not but we clear the
 	 * "valid" bool so this field is no longer valid.
 	 */
 	memset(&info->status.ack_signal, 0, sizeof(*info) -
 	    offsetof(struct ieee80211_tx_info, status.ack_signal));
 }
 
 static __inline void
 ieee80211_txq_get_depth(struct ieee80211_txq *txq, unsigned long *frame_cnt,
     unsigned long *byte_cnt)
 {
 
 	if (frame_cnt == NULL && byte_cnt == NULL)
 		return;
 
 	linuxkpi_ieee80211_txq_get_depth(txq, frame_cnt, byte_cnt);
 }
 
 static __inline int
 rate_lowest_index(struct ieee80211_supported_band *band,
     struct ieee80211_sta *sta)
 {
 	IMPROVE();
 	return (0);
 }
 
 
 static __inline void
 SET_IEEE80211_PERM_ADDR	(struct ieee80211_hw *hw, uint8_t *addr)
 {
 
 	ether_addr_copy(hw->wiphy->perm_addr, addr);
 }
 
 static __inline void
 ieee80211_report_low_ack(struct ieee80211_sta *sta, int x)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_tx_rate_update(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
     struct ieee80211_tx_info *info)
 {
 	TODO();
 }
 
 static __inline bool
 ieee80211_txq_may_transmit(struct ieee80211_hw *hw, struct ieee80211_txq *txq)
 {
 	TODO();
 	return (false);
 }
 
 static __inline void
 ieee80211_radar_detected(struct ieee80211_hw *hw)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_sta_register_airtime(struct ieee80211_sta *sta,
     uint8_t tid, uint32_t duration, int x)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_beacon_set_cntdwn(struct ieee80211_vif *vif, u8 counter)
 {
 	TODO();
 }
 
 static __inline int
 ieee80211_beacon_update_cntdwn(struct ieee80211_vif *vif)
 {
 	TODO();
 	return (-1);
 }
 
 static __inline int
 ieee80211_get_vht_max_nss(struct ieee80211_vht_cap *vht_cap, uint32_t chanwidth,
     int x, bool t, int nss)
 {
 	TODO();
 	return (-1);
 }
 
 static __inline bool
 ieee80211_beacon_cntdwn_is_complete(struct ieee80211_vif *vif)
 {
 	TODO();
 	return (true);
 }
 
 static __inline void
 ieee80211_disconnect(struct ieee80211_vif *vif, bool _x)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_channel_switch_disconnect(struct ieee80211_vif *vif, bool _x)
 {
 	TODO();
 }
 
 static __inline const struct ieee80211_sta_he_cap *
 ieee80211_get_he_iftype_cap(const struct ieee80211_supported_band *band,
     enum nl80211_iftype type)
 {
 	TODO();
         return (NULL);
 }
 
 static __inline void
 ieee80211_key_mic_failure(struct ieee80211_key_conf *key)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_key_replay(struct ieee80211_key_conf *key)
 {
 	TODO();
 }
 
 static __inline uint32_t
 ieee80211_calc_rx_airtime(struct ieee80211_hw *hw,
     struct ieee80211_rx_status *rxstat, int len)
 {
 	TODO();
 	return (0);
 }
 
 static __inline void
 ieee80211_get_tx_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
     struct sk_buff *skb, struct ieee80211_tx_rate *txrate, int nrates)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_color_change_finish(struct ieee80211_vif *vif)
 {
 	TODO();
 }
 
 static __inline struct sk_buff *
 ieee80211_get_fils_discovery_tmpl(struct ieee80211_hw *hw,
     struct ieee80211_vif *vif)
 {
 	TODO();
 	return (NULL);
 }
 
 static __inline struct sk_buff *
 ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw,
     struct ieee80211_vif *vif)
 {
 	TODO();
 	return (NULL);
 }
 
 static __inline void
 linuxkpi_ieee80211_send_bar(struct ieee80211_vif *vif, uint8_t *ra, uint16_t tid,
     uint16_t ssn)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_resume_disconnect(struct ieee80211_vif *vif)
 {
         TODO();
 }
 
 static __inline int
 ieee80211_data_to_8023(struct sk_buff *skb, const uint8_t *addr,
      enum nl80211_iftype iftype)
 {
         TODO();
         return (-1);
 }
 
 static __inline void
 ieee80211_get_tkip_p1k_iv(struct ieee80211_key_conf *key,
     uint32_t iv32, uint16_t *p1k)
 {
         TODO();
 }
 
 static __inline struct ieee80211_key_conf *
 ieee80211_gtk_rekey_add(struct ieee80211_vif *vif,
     struct ieee80211_key_conf *key)
 {
         TODO();
         return (NULL);
 }
 
 static __inline void
 ieee80211_gtk_rekey_notify(struct ieee80211_vif *vif, const uint8_t *bssid,
     const uint8_t *replay_ctr, gfp_t gfp)
 {
         TODO();
 }
 
 static __inline void
 ieee80211_remove_key(struct ieee80211_key_conf *key)
 {
         TODO();
 }
 
 static __inline void
 ieee80211_set_key_rx_seq(struct ieee80211_key_conf *key, int tid,
     struct ieee80211_key_seq *seq)
 {
         TODO();
 }
 
 static __inline void
 ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
     struct cfg80211_wowlan_wakeup *wakeup, gfp_t gfp)
 {
         TODO();
 }
 
 static __inline void
 ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
     uint64_t obss_color_bitmap, gfp_t gfp)
 {
 	TODO();
 }
 
 static __inline void
 ieee80211_refresh_tx_agg_session_timer(struct ieee80211_sta *sta,
     uint8_t tid)
 {
 	TODO();
 }
 
 static __inline struct ieee80211_ema_beacons *
 ieee80211_beacon_get_template_ema_list(struct ieee80211_hw *hw,
     struct ieee80211_vif *vif, uint32_t link_id)
 {
 	TODO();
 	return (NULL);
 }
 
 static __inline void
 ieee80211_beacon_free_ema_list(struct ieee80211_ema_beacons *bcns)
 {
 	TODO();
 }
 
 static inline bool
 ieee80211_vif_is_mld(const struct ieee80211_vif *vif)
 {
 
 	/* If valid_links is non-zero, the vif is an MLD. */
 	return (vif->valid_links != 0);
 }
 
 static __inline const struct ieee80211_sta_he_cap *
 ieee80211_get_he_iftype_cap_vif(const struct ieee80211_supported_band *band,
     struct ieee80211_vif *vif)
 {
 	TODO();
 	return (NULL);
 }
 
 static __inline const struct ieee80211_sta_eht_cap *
 ieee80211_get_eht_iftype_cap_vif(const struct ieee80211_supported_band *band,
     struct ieee80211_vif *vif)
 {
 	TODO();
 	return (NULL);
 }
 
 #define	ieee80211_send_bar(_v, _r, _t, _s)				\
     linuxkpi_ieee80211_send_bar(_v, _r, _t, _s)
 
 #endif	/* _LINUXKPI_NET_MAC80211_H */