root/include/linux/ieee80211-ht.h
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * IEEE 802.11 HT definitions
 *
 * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
 * <jkmaline@cc.hut.fi>
 * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
 * Copyright (c) 2005, Devicescape Software, Inc.
 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
 * Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH
 * Copyright (c) 2016 - 2017 Intel Deutschland GmbH
 * Copyright (c) 2018 - 2025 Intel Corporation
 */

#ifndef LINUX_IEEE80211_HT_H
#define LINUX_IEEE80211_HT_H

#include <linux/types.h>
#include <linux/if_ether.h>

/* Maximal size of an A-MSDU that can be transported in a HT BA session */
#define IEEE80211_MAX_MPDU_LEN_HT_BA            4095

/* Maximal size of an A-MSDU */
#define IEEE80211_MAX_MPDU_LEN_HT_3839          3839
#define IEEE80211_MAX_MPDU_LEN_HT_7935          7935

#define IEEE80211_HT_CTL_LEN            4

enum ieee80211_ht_chanwidth_values {
        IEEE80211_HT_CHANWIDTH_20MHZ = 0,
        IEEE80211_HT_CHANWIDTH_ANY = 1,
};

/**
 * struct ieee80211_bar - Block Ack Request frame format
 * @frame_control: Frame Control
 * @duration: Duration
 * @ra: RA
 * @ta: TA
 * @control: BAR Control
 * @start_seq_num: Starting Sequence Number (see Figure 9-37)
 *
 * This structure represents the "BlockAckReq frame format"
 * as described in IEEE Std 802.11-2020 section 9.3.1.7.
*/
struct ieee80211_bar {
        __le16 frame_control;
        __le16 duration;
        __u8 ra[ETH_ALEN];
        __u8 ta[ETH_ALEN];
        __le16 control;
        __le16 start_seq_num;
} __packed;

/* 802.11 BAR control masks */
#define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL    0x0000
#define IEEE80211_BAR_CTRL_MULTI_TID            0x0002
#define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004
#define IEEE80211_BAR_CTRL_TID_INFO_MASK        0xf000
#define IEEE80211_BAR_CTRL_TID_INFO_SHIFT       12

#define IEEE80211_HT_MCS_MASK_LEN               10

/**
 * struct ieee80211_mcs_info - Supported MCS Set field
 * @rx_mask: RX mask
 * @rx_highest: highest supported RX rate. If set represents
 *      the highest supported RX data rate in units of 1 Mbps.
 *      If this field is 0 this value should not be used to
 *      consider the highest RX data rate supported.
 * @tx_params: TX parameters
 * @reserved: Reserved bits
 *
 * This structure represents the "Supported MCS Set field" as
 * described in IEEE Std 802.11-2020 section 9.4.2.55.4.
 */
struct ieee80211_mcs_info {
        u8 rx_mask[IEEE80211_HT_MCS_MASK_LEN];
        __le16 rx_highest;
        u8 tx_params;
        u8 reserved[3];
} __packed;

/* 802.11n HT capability MSC set */
#define IEEE80211_HT_MCS_RX_HIGHEST_MASK        0x3ff
#define IEEE80211_HT_MCS_TX_DEFINED             0x01
#define IEEE80211_HT_MCS_TX_RX_DIFF             0x02
/* value 0 == 1 stream etc */
#define IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK    0x0C
#define IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT   2
#define         IEEE80211_HT_MCS_TX_MAX_STREAMS 4
#define IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION  0x10

#define IEEE80211_HT_MCS_CHAINS(mcs) ((mcs) == 32 ? 1 : (1 + ((mcs) >> 3)))

/*
 * 802.11n D5.0 20.3.5 / 20.6 says:
 * - indices 0 to 7 and 32 are single spatial stream
 * - 8 to 31 are multiple spatial streams using equal modulation
 *   [8..15 for two streams, 16..23 for three and 24..31 for four]
 * - remainder are multiple spatial streams using unequal modulation
 */
#define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START 33
#define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE \
        (IEEE80211_HT_MCS_UNEQUAL_MODULATION_START / 8)

/**
 * struct ieee80211_ht_cap - HT capabilities element
 * @cap_info: HT Capability Information
 * @ampdu_params_info: A-MPDU Parameters
 * @mcs: Supported MCS Set
 * @extended_ht_cap_info: HT Extended Capabilities
 * @tx_BF_cap_info: Transmit Beamforming Capabilities
 * @antenna_selection_info: ASEL Capability
 *
 * This structure represents the payload of the "HT Capabilities
 * element" as described in IEEE Std 802.11-2020 section 9.4.2.55.
 */
struct ieee80211_ht_cap {
        __le16 cap_info;
        u8 ampdu_params_info;

        /* 16 bytes MCS information */
        struct ieee80211_mcs_info mcs;

        __le16 extended_ht_cap_info;
        __le32 tx_BF_cap_info;
        u8 antenna_selection_info;
} __packed;

/* 802.11n HT capabilities masks (for cap_info) */
#define IEEE80211_HT_CAP_LDPC_CODING            0x0001
#define IEEE80211_HT_CAP_SUP_WIDTH_20_40        0x0002
#define IEEE80211_HT_CAP_SM_PS                  0x000C
#define         IEEE80211_HT_CAP_SM_PS_SHIFT    2
#define IEEE80211_HT_CAP_GRN_FLD                0x0010
#define IEEE80211_HT_CAP_SGI_20                 0x0020
#define IEEE80211_HT_CAP_SGI_40                 0x0040
#define IEEE80211_HT_CAP_TX_STBC                0x0080
#define IEEE80211_HT_CAP_RX_STBC                0x0300
#define         IEEE80211_HT_CAP_RX_STBC_SHIFT  8
#define IEEE80211_HT_CAP_DELAY_BA               0x0400
#define IEEE80211_HT_CAP_MAX_AMSDU              0x0800
#define IEEE80211_HT_CAP_DSSSCCK40              0x1000
#define IEEE80211_HT_CAP_RESERVED               0x2000
#define IEEE80211_HT_CAP_40MHZ_INTOLERANT       0x4000
#define IEEE80211_HT_CAP_LSIG_TXOP_PROT         0x8000

/* 802.11n HT extended capabilities masks (for extended_ht_cap_info) */
#define IEEE80211_HT_EXT_CAP_PCO                0x0001
#define IEEE80211_HT_EXT_CAP_PCO_TIME           0x0006
#define         IEEE80211_HT_EXT_CAP_PCO_TIME_SHIFT     1
#define IEEE80211_HT_EXT_CAP_MCS_FB             0x0300
#define         IEEE80211_HT_EXT_CAP_MCS_FB_SHIFT       8
#define IEEE80211_HT_EXT_CAP_HTC_SUP            0x0400
#define IEEE80211_HT_EXT_CAP_RD_RESPONDER       0x0800

/* 802.11n HT capability AMPDU settings (for ampdu_params_info) */
#define IEEE80211_HT_AMPDU_PARM_FACTOR          0x03
#define IEEE80211_HT_AMPDU_PARM_DENSITY         0x1C
#define         IEEE80211_HT_AMPDU_PARM_DENSITY_SHIFT   2

/*
 * Maximum length of AMPDU that the STA can receive in high-throughput (HT).
 * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
 */
enum ieee80211_max_ampdu_length_exp {
        IEEE80211_HT_MAX_AMPDU_8K = 0,
        IEEE80211_HT_MAX_AMPDU_16K = 1,
        IEEE80211_HT_MAX_AMPDU_32K = 2,
        IEEE80211_HT_MAX_AMPDU_64K = 3
};

#define IEEE80211_HT_MAX_AMPDU_FACTOR 13

/* Minimum MPDU start spacing */
enum ieee80211_min_mpdu_spacing {
        IEEE80211_HT_MPDU_DENSITY_NONE = 0,     /* No restriction */
        IEEE80211_HT_MPDU_DENSITY_0_25 = 1,     /* 1/4 usec */
        IEEE80211_HT_MPDU_DENSITY_0_5 = 2,      /* 1/2 usec */
        IEEE80211_HT_MPDU_DENSITY_1 = 3,        /* 1 usec */
        IEEE80211_HT_MPDU_DENSITY_2 = 4,        /* 2 usec */
        IEEE80211_HT_MPDU_DENSITY_4 = 5,        /* 4 usec */
        IEEE80211_HT_MPDU_DENSITY_8 = 6,        /* 8 usec */
        IEEE80211_HT_MPDU_DENSITY_16 = 7        /* 16 usec */
};

/**
 * struct ieee80211_ht_operation - HT operation IE
 * @primary_chan: Primary Channel
 * @ht_param: HT Operation Information parameters
 * @operation_mode: HT Operation Information operation mode
 * @stbc_param: HT Operation Information STBC params
 * @basic_set: Basic HT-MCS Set
 *
 * This structure represents the payload of the "HT Operation
 * element" as described in IEEE Std 802.11-2020 section 9.4.2.56.
 */
struct ieee80211_ht_operation {
        u8 primary_chan;
        u8 ht_param;
        __le16 operation_mode;
        __le16 stbc_param;
        u8 basic_set[16];
} __packed;

/* for ht_param */
#define IEEE80211_HT_PARAM_CHA_SEC_OFFSET               0x03
#define         IEEE80211_HT_PARAM_CHA_SEC_NONE         0x00
#define         IEEE80211_HT_PARAM_CHA_SEC_ABOVE        0x01
#define         IEEE80211_HT_PARAM_CHA_SEC_BELOW        0x03
#define IEEE80211_HT_PARAM_CHAN_WIDTH_ANY               0x04
#define IEEE80211_HT_PARAM_RIFS_MODE                    0x08

/* for operation_mode */
#define IEEE80211_HT_OP_MODE_PROTECTION                 0x0003
#define         IEEE80211_HT_OP_MODE_PROTECTION_NONE            0
#define         IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER       1
#define         IEEE80211_HT_OP_MODE_PROTECTION_20MHZ           2
#define         IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED     3
#define IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT           0x0004
#define IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT           0x0010
#define IEEE80211_HT_OP_MODE_CCFS2_SHIFT                5
#define IEEE80211_HT_OP_MODE_CCFS2_MASK                 0x1fe0

/* for stbc_param */
#define IEEE80211_HT_STBC_PARAM_DUAL_BEACON             0x0040
#define IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT           0x0080
#define IEEE80211_HT_STBC_PARAM_STBC_BEACON             0x0100
#define IEEE80211_HT_STBC_PARAM_LSIG_TXOP_FULLPROT      0x0200
#define IEEE80211_HT_STBC_PARAM_PCO_ACTIVE              0x0400
#define IEEE80211_HT_STBC_PARAM_PCO_PHASE               0x0800


/* block-ack parameters */
#define IEEE80211_ADDBA_PARAM_AMSDU_MASK 0x0001
#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFC0
#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800

/*
 * A-MPDU buffer sizes
 * According to HT size varies from 8 to 64 frames
 * HE adds the ability to have up to 256 frames.
 * EHT adds the ability to have up to 1K frames.
 */
#define IEEE80211_MIN_AMPDU_BUF         0x8
#define IEEE80211_MAX_AMPDU_BUF_HT      0x40
#define IEEE80211_MAX_AMPDU_BUF_HE      0x100
#define IEEE80211_MAX_AMPDU_BUF_EHT     0x400


/* Spatial Multiplexing Power Save Modes (for capability) */
#define WLAN_HT_CAP_SM_PS_STATIC        0
#define WLAN_HT_CAP_SM_PS_DYNAMIC       1
#define WLAN_HT_CAP_SM_PS_INVALID       2
#define WLAN_HT_CAP_SM_PS_DISABLED      3

/* for SM power control field lower two bits */
#define WLAN_HT_SMPS_CONTROL_DISABLED   0
#define WLAN_HT_SMPS_CONTROL_STATIC     1
#define WLAN_HT_SMPS_CONTROL_DYNAMIC    3

/* HT action codes */
enum ieee80211_ht_actioncode {
        WLAN_HT_ACTION_NOTIFY_CHANWIDTH = 0,
        WLAN_HT_ACTION_SMPS = 1,
        WLAN_HT_ACTION_PSMP = 2,
        WLAN_HT_ACTION_PCO_PHASE = 3,
        WLAN_HT_ACTION_CSI = 4,
        WLAN_HT_ACTION_NONCOMPRESSED_BF = 5,
        WLAN_HT_ACTION_COMPRESSED_BF = 6,
        WLAN_HT_ACTION_ASEL_IDX_FEEDBACK = 7,
};

/* BACK action code */
enum ieee80211_back_actioncode {
        WLAN_ACTION_ADDBA_REQ = 0,
        WLAN_ACTION_ADDBA_RESP = 1,
        WLAN_ACTION_DELBA = 2,
};

/* BACK (block-ack) parties */
enum ieee80211_back_parties {
        WLAN_BACK_RECIPIENT = 0,
        WLAN_BACK_INITIATOR = 1,
};

#endif /* LINUX_IEEE80211_HT_H */