Skip to content

Commit 072e6f7

Browse files
committed
wifi: cfg80211: add initial UHR support
Add initial support for making UHR connections (or suppressing that), adding UHR capable stations on the AP side, encoding and decoding UHR MCSes (except rate calculation for the new MCSes 17, 19, 20 and 23) as well as regulatory support. Link: https://patch.msgid.link/20260130164259.54cc12fbb307.I26126bebd83c7ab17e99827489f946ceabb3521f@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
1 parent a7cb501 commit 072e6f7

5 files changed

Lines changed: 265 additions & 30 deletions

File tree

include/net/cfg80211.h

Lines changed: 55 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
88
* Copyright 2013-2014 Intel Mobile Communications GmbH
99
* Copyright 2015-2017 Intel Deutschland GmbH
10-
* Copyright (C) 2018-2025 Intel Corporation
10+
* Copyright (C) 2018-2026 Intel Corporation
1111
*/
1212

1313
#include <linux/ethtool.h>
@@ -126,6 +126,7 @@ struct wiphy;
126126
* @IEEE80211_CHAN_NO_4MHZ: 4 MHz bandwidth is not permitted on this channel.
127127
* @IEEE80211_CHAN_NO_8MHZ: 8 MHz bandwidth is not permitted on this channel.
128128
* @IEEE80211_CHAN_NO_16MHZ: 16 MHz bandwidth is not permitted on this channel.
129+
* @IEEE80211_CHAN_NO_UHR: UHR operation is not permitted on this channel.
129130
*/
130131
enum ieee80211_channel_flags {
131132
IEEE80211_CHAN_DISABLED = BIT(0),
@@ -143,6 +144,7 @@ enum ieee80211_channel_flags {
143144
IEEE80211_CHAN_NO_10MHZ = BIT(12),
144145
IEEE80211_CHAN_NO_HE = BIT(13),
145146
/* can use free bits here */
147+
IEEE80211_CHAN_NO_UHR = BIT(18),
146148
IEEE80211_CHAN_NO_320MHZ = BIT(19),
147149
IEEE80211_CHAN_NO_EHT = BIT(20),
148150
IEEE80211_CHAN_DFS_CONCURRENT = BIT(21),
@@ -429,6 +431,18 @@ struct ieee80211_sta_eht_cap {
429431
u8 eht_ppe_thres[IEEE80211_EHT_PPE_THRES_MAX_LEN];
430432
};
431433

434+
/**
435+
* struct ieee80211_sta_uhr_cap - STA's UHR capabilities
436+
* @has_uhr: true iff UHR is supported and data is valid
437+
* @mac: fixed MAC capabilities
438+
* @phy: fixed PHY capabilities
439+
*/
440+
struct ieee80211_sta_uhr_cap {
441+
bool has_uhr;
442+
struct ieee80211_uhr_cap_mac mac;
443+
struct ieee80211_uhr_cap_phy phy;
444+
};
445+
432446
/* sparse defines __CHECKER__; see Documentation/dev-tools/sparse.rst */
433447
#ifdef __CHECKER__
434448
/*
@@ -454,6 +468,7 @@ struct ieee80211_sta_eht_cap {
454468
* @he_6ghz_capa: HE 6 GHz capabilities, must be filled in for a
455469
* 6 GHz band channel (and 0 may be valid value).
456470
* @eht_cap: STA's EHT capabilities
471+
* @uhr_cap: STA's UHR capabilities
457472
* @vendor_elems: vendor element(s) to advertise
458473
* @vendor_elems.data: vendor element(s) data
459474
* @vendor_elems.len: vendor element(s) length
@@ -463,6 +478,7 @@ struct ieee80211_sband_iftype_data {
463478
struct ieee80211_sta_he_cap he_cap;
464479
struct ieee80211_he_6ghz_capa he_6ghz_capa;
465480
struct ieee80211_sta_eht_cap eht_cap;
481+
struct ieee80211_sta_uhr_cap uhr_cap;
466482
struct {
467483
const u8 *data;
468484
unsigned int len;
@@ -704,6 +720,26 @@ ieee80211_get_eht_iftype_cap(const struct ieee80211_supported_band *sband,
704720
return NULL;
705721
}
706722

723+
/**
724+
* ieee80211_get_uhr_iftype_cap - return UHR capabilities for an sband's iftype
725+
* @sband: the sband to search for the iftype on
726+
* @iftype: enum nl80211_iftype
727+
*
728+
* Return: pointer to the struct ieee80211_sta_uhr_cap, or NULL is none found
729+
*/
730+
static inline const struct ieee80211_sta_uhr_cap *
731+
ieee80211_get_uhr_iftype_cap(const struct ieee80211_supported_band *sband,
732+
enum nl80211_iftype iftype)
733+
{
734+
const struct ieee80211_sband_iftype_data *data =
735+
ieee80211_get_sband_iftype_data(sband, iftype);
736+
737+
if (data && data->uhr_cap.has_uhr)
738+
return &data->uhr_cap;
739+
740+
return NULL;
741+
}
742+
707743
/**
708744
* wiphy_read_of_freq_limits - read frequency limits from device tree
709745
*
@@ -1486,6 +1522,7 @@ struct cfg80211_s1g_short_beacon {
14861522
* @he_cap: HE capabilities (or %NULL if HE isn't enabled)
14871523
* @eht_cap: EHT capabilities (or %NULL if EHT isn't enabled)
14881524
* @eht_oper: EHT operation IE (or %NULL if EHT isn't enabled)
1525+
* @uhr_oper: UHR operation (or %NULL if UHR isn't enabled)
14891526
* @ht_required: stations must support HT
14901527
* @vht_required: stations must support VHT
14911528
* @twt_responder: Enable Target Wait Time
@@ -1525,6 +1562,7 @@ struct cfg80211_ap_settings {
15251562
const struct ieee80211_he_operation *he_oper;
15261563
const struct ieee80211_eht_cap_elem *eht_cap;
15271564
const struct ieee80211_eht_operation *eht_oper;
1565+
const struct ieee80211_uhr_operation *uhr_oper;
15281566
bool ht_required, vht_required, he_required, sae_h2e_required;
15291567
bool twt_responder;
15301568
u32 flags;
@@ -1698,6 +1736,8 @@ struct sta_txpwr {
16981736
* @eht_capa: EHT capabilities of station
16991737
* @eht_capa_len: the length of the EHT capabilities
17001738
* @s1g_capa: S1G capabilities of station
1739+
* @uhr_capa: UHR capabilities of the station
1740+
* @uhr_capa_len: the length of the UHR capabilities
17011741
*/
17021742
struct link_station_parameters {
17031743
const u8 *mld_mac;
@@ -1717,6 +1757,8 @@ struct link_station_parameters {
17171757
const struct ieee80211_eht_cap_elem *eht_capa;
17181758
u8 eht_capa_len;
17191759
const struct ieee80211_s1g_cap *s1g_capa;
1760+
const struct ieee80211_uhr_cap *uhr_capa;
1761+
u8 uhr_capa_len;
17201762
};
17211763

17221764
/**
@@ -1898,6 +1940,11 @@ int cfg80211_check_station_change(struct wiphy *wiphy,
18981940
* @RATE_INFO_FLAGS_EXTENDED_SC_DMG: 60GHz extended SC MCS
18991941
* @RATE_INFO_FLAGS_EHT_MCS: EHT MCS information
19001942
* @RATE_INFO_FLAGS_S1G_MCS: MCS field filled with S1G MCS
1943+
* @RATE_INFO_FLAGS_UHR_MCS: UHR MCS information
1944+
* @RATE_INFO_FLAGS_UHR_ELR_MCS: UHR ELR MCS was used
1945+
* (set together with @RATE_INFO_FLAGS_UHR_MCS)
1946+
* @RATE_INFO_FLAGS_UHR_IM: UHR Interference Mitigation
1947+
* was used
19011948
*/
19021949
enum rate_info_flags {
19031950
RATE_INFO_FLAGS_MCS = BIT(0),
@@ -1909,6 +1956,9 @@ enum rate_info_flags {
19091956
RATE_INFO_FLAGS_EXTENDED_SC_DMG = BIT(6),
19101957
RATE_INFO_FLAGS_EHT_MCS = BIT(7),
19111958
RATE_INFO_FLAGS_S1G_MCS = BIT(8),
1959+
RATE_INFO_FLAGS_UHR_MCS = BIT(9),
1960+
RATE_INFO_FLAGS_UHR_ELR_MCS = BIT(10),
1961+
RATE_INFO_FLAGS_UHR_IM = BIT(11),
19121962
};
19131963

19141964
/**
@@ -1924,7 +1974,7 @@ enum rate_info_flags {
19241974
* @RATE_INFO_BW_160: 160 MHz bandwidth
19251975
* @RATE_INFO_BW_HE_RU: bandwidth determined by HE RU allocation
19261976
* @RATE_INFO_BW_320: 320 MHz bandwidth
1927-
* @RATE_INFO_BW_EHT_RU: bandwidth determined by EHT RU allocation
1977+
* @RATE_INFO_BW_EHT_RU: bandwidth determined by EHT/UHR RU allocation
19281978
* @RATE_INFO_BW_1: 1 MHz bandwidth
19291979
* @RATE_INFO_BW_2: 2 MHz bandwidth
19301980
* @RATE_INFO_BW_4: 4 MHz bandwidth
@@ -1955,7 +2005,7 @@ enum rate_info_bw {
19552005
*
19562006
* @flags: bitflag of flags from &enum rate_info_flags
19572007
* @legacy: bitrate in 100kbit/s for 802.11abg
1958-
* @mcs: mcs index if struct describes an HT/VHT/HE/EHT/S1G rate
2008+
* @mcs: mcs index if struct describes an HT/VHT/HE/EHT/S1G/UHR rate
19592009
* @nss: number of streams (VHT & HE only)
19602010
* @bw: bandwidth (from &enum rate_info_bw)
19612011
* @he_gi: HE guard interval (from &enum nl80211_he_gi)
@@ -3262,6 +3312,7 @@ struct cfg80211_ml_reconf_req {
32623312
* Drivers shall disable MLO features for the current association if this
32633313
* flag is not set.
32643314
* @ASSOC_REQ_SPP_AMSDU: SPP A-MSDUs will be used on this connection (if any)
3315+
* @ASSOC_REQ_DISABLE_UHR: Disable UHR
32653316
*/
32663317
enum cfg80211_assoc_req_flags {
32673318
ASSOC_REQ_DISABLE_HT = BIT(0),
@@ -3272,6 +3323,7 @@ enum cfg80211_assoc_req_flags {
32723323
ASSOC_REQ_DISABLE_EHT = BIT(5),
32733324
CONNECT_REQ_MLO_SUPPORT = BIT(6),
32743325
ASSOC_REQ_SPP_AMSDU = BIT(7),
3326+
ASSOC_REQ_DISABLE_UHR = BIT(8),
32753327
};
32763328

32773329
/**

include/uapi/linux/nl80211.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2977,6 +2977,13 @@ enum nl80211_commands {
29772977
* @NL80211_ATTR_EPP_PEER: A flag attribute to indicate if the peer is an EPP
29782978
* STA. Used with %NL80211_CMD_NEW_STA and %NL80211_CMD_ADD_LINK_STA
29792979
*
2980+
* @NL80211_ATTR_UHR_CAPABILITY: UHR Capability information element (from
2981+
* association request when used with NL80211_CMD_NEW_STATION). Can be set
2982+
* only if HE/EHT are also available.
2983+
* @NL80211_ATTR_DISABLE_UHR: Force UHR capable interfaces to disable
2984+
* this feature during association. This is a flag attribute.
2985+
* Currently only supported in mac80211 drivers.
2986+
*
29802987
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
29812988
* @NL80211_ATTR_MAX: highest attribute number currently defined
29822989
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -3547,6 +3554,9 @@ enum nl80211_attrs {
35473554

35483555
NL80211_ATTR_EPP_PEER,
35493556

3557+
NL80211_ATTR_UHR_CAPABILITY,
3558+
NL80211_ATTR_DISABLE_UHR,
3559+
35503560
/* add attributes here, update the policy in nl80211.c */
35513561

35523562
__NL80211_ATTR_AFTER_LAST,
@@ -3899,6 +3909,12 @@ enum nl80211_eht_ru_alloc {
38993909
* @NL80211_RATE_INFO_4_MHZ_WIDTH: 4 MHz S1G rate
39003910
* @NL80211_RATE_INFO_8_MHZ_WIDTH: 8 MHz S1G rate
39013911
* @NL80211_RATE_INFO_16_MHZ_WIDTH: 16 MHz S1G rate
3912+
* @NL80211_RATE_INFO_UHR_MCS: UHR MCS index (u8, 0-15, 17, 19, 20, 23)
3913+
* Note that the other EHT attributes (such as @NL80211_RATE_INFO_EHT_NSS)
3914+
* are used in conjunction with this where applicable
3915+
* @NL80211_RATE_INFO_UHR_ELR: UHR ELR flag, which restricts NSS to 1,
3916+
* MCS to 0 or 1, and GI to %NL80211_RATE_INFO_EHT_GI_1_6.
3917+
* @NL80211_RATE_INFO_UHR_IM: UHR Interference Mitigation flag
39023918
* @__NL80211_RATE_INFO_AFTER_LAST: internal use
39033919
*/
39043920
enum nl80211_rate_info {
@@ -3932,6 +3948,9 @@ enum nl80211_rate_info {
39323948
NL80211_RATE_INFO_4_MHZ_WIDTH,
39333949
NL80211_RATE_INFO_8_MHZ_WIDTH,
39343950
NL80211_RATE_INFO_16_MHZ_WIDTH,
3951+
NL80211_RATE_INFO_UHR_MCS,
3952+
NL80211_RATE_INFO_UHR_ELR,
3953+
NL80211_RATE_INFO_UHR_IM,
39353954

39363955
/* keep last */
39373956
__NL80211_RATE_INFO_AFTER_LAST,
@@ -4254,6 +4273,10 @@ enum nl80211_mpath_info {
42544273
* capabilities element
42554274
* @NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE: EHT PPE thresholds information as
42564275
* defined in EHT capabilities element
4276+
* @NL80211_BAND_IFTYPE_ATTR_UHR_CAP_MAC: UHR MAC capabilities as in UHR
4277+
* capabilities element
4278+
* @NL80211_BAND_IFTYPE_ATTR_UHR_CAP_PHY: UHR PHY capabilities as in UHR
4279+
* capabilities element
42574280
* @__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST: internal use
42584281
* @NL80211_BAND_IFTYPE_ATTR_MAX: highest band attribute currently defined
42594282
*/
@@ -4271,6 +4294,8 @@ enum nl80211_band_iftype_attr {
42714294
NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PHY,
42724295
NL80211_BAND_IFTYPE_ATTR_EHT_CAP_MCS_SET,
42734296
NL80211_BAND_IFTYPE_ATTR_EHT_CAP_PPE,
4297+
NL80211_BAND_IFTYPE_ATTR_UHR_CAP_MAC,
4298+
NL80211_BAND_IFTYPE_ATTR_UHR_CAP_PHY,
42744299

42754300
/* keep last */
42764301
__NL80211_BAND_IFTYPE_ATTR_AFTER_LAST,
@@ -4453,6 +4478,8 @@ enum nl80211_wmm_rule {
44534478
* @NL80211_FREQUENCY_ATTR_S1G_NO_PRIMARY: Channel is not permitted for use
44544479
* as a primary channel. Does not prevent the channel from existing
44554480
* as a non-primary subchannel. Only applicable to S1G channels.
4481+
* @NL80211_FREQUENCY_ATTR_NO_UHR: UHR operation is not allowed on this channel
4482+
* in current regulatory domain.
44564483
* @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number
44574484
* currently defined
44584485
* @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use
@@ -4502,6 +4529,7 @@ enum nl80211_frequency_attr {
45024529
NL80211_FREQUENCY_ATTR_NO_8MHZ,
45034530
NL80211_FREQUENCY_ATTR_NO_16MHZ,
45044531
NL80211_FREQUENCY_ATTR_S1G_NO_PRIMARY,
4532+
NL80211_FREQUENCY_ATTR_NO_UHR,
45054533

45064534
/* keep last */
45074535
__NL80211_FREQUENCY_ATTR_AFTER_LAST,
@@ -4715,6 +4743,7 @@ enum nl80211_sched_scan_match_attr {
47154743
* despite NO_IR configuration.
47164744
* @NL80211_RRF_ALLOW_20MHZ_ACTIVITY: Allow activity in 20 MHz bandwidth,
47174745
* despite NO_IR configuration.
4746+
* @NL80211_RRF_NO_UHR: UHR operation not allowed
47184747
*/
47194748
enum nl80211_reg_rule_flags {
47204749
NL80211_RRF_NO_OFDM = 1 << 0,
@@ -4741,6 +4770,7 @@ enum nl80211_reg_rule_flags {
47414770
NL80211_RRF_NO_6GHZ_AFC_CLIENT = 1 << 23,
47424771
NL80211_RRF_ALLOW_6GHZ_VLP_AP = 1 << 24,
47434772
NL80211_RRF_ALLOW_20MHZ_ACTIVITY = 1 << 25,
4773+
NL80211_RRF_NO_UHR = 1 << 26,
47444774
};
47454775

47464776
#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR

0 commit comments

Comments
 (0)