[PATCH v3 5/8] ap: advertise DBE capability if driver has it
Johannes Berg
johannes at sipsolutions.net
Fri Apr 24 00:11:57 PDT 2026
From: Johannes Berg <johannes.berg at intel.com>
If the driver has DBE capability, then the DBE capabilities
field must be created. Do this based on the EHT capability
the driver is advertising.
Signed-off-by: Johannes Berg <johannes.berg at intel.com>
---
src/ap/ieee802_11_uhr.c | 43 ++++++++++++++++++++++++++++++++++--
src/common/ieee802_11_defs.h | 9 ++++++++
2 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/src/ap/ieee802_11_uhr.c b/src/ap/ieee802_11_uhr.c
index 6538e0e0b9ea..2476b3412b75 100644
--- a/src/ap/ieee802_11_uhr.c
+++ b/src/ap/ieee802_11_uhr.c
@@ -24,6 +24,7 @@ size_t hostapd_eid_uhr_capab_len(struct hostapd_data *hapd,
{
struct hostapd_hw_modes *mode;
struct uhr_capabilities *uhr_cap;
+ size_t len = 3 /* ext elem header */ + 6 /* MAC + PHY */;
mode = hapd->iface->current_mode;
if (!mode)
@@ -33,7 +34,10 @@ size_t hostapd_eid_uhr_capab_len(struct hostapd_data *hapd,
if (!uhr_cap->uhr_supported)
return 0;
- return 3 /* ext elem header */ + 6 /* MAC + PHY */;
+ if (uhr_cap->mac[1] & IEEE80211_UHR_MAC_CAP1_DBE_SUPP)
+ len++;
+
+ return len;
}
@@ -41,6 +45,8 @@ u8 * hostapd_eid_uhr_capab(struct hostapd_data *hapd, u8 *eid,
enum ieee80211_op_mode opmode)
{
struct hostapd_hw_modes *mode;
+ struct he_capabilities *he_cap;
+ struct eht_capabilities *eht_cap;
struct uhr_capabilities *uhr_cap;
struct ieee80211_uhr_capabilities *cap;
u8 *pos = eid, *length_pos;
@@ -49,8 +55,12 @@ u8 * hostapd_eid_uhr_capab(struct hostapd_data *hapd, u8 *eid,
if (!mode)
return eid;
+ he_cap = &mode->he_capab[opmode];
+ eht_cap = &mode->eht_capab[opmode];
uhr_cap = &mode->uhr_capab[opmode];
- if (!uhr_cap->uhr_supported)
+ if (!he_cap->he_supported ||
+ !eht_cap->eht_supported ||
+ !uhr_cap->uhr_supported)
return eid;
*pos++ = WLAN_EID_EXTENSION;
@@ -62,6 +72,35 @@ u8 * hostapd_eid_uhr_capab(struct hostapd_data *hapd, u8 *eid,
os_memcpy(cap->phy, uhr_cap->phy, sizeof(cap->phy));
pos += sizeof(*cap);
+ if (opmode == IEEE80211_MODE_AP &&
+ cap->mac[1] & IEEE80211_UHR_MAC_CAP1_DBE_SUPP) {
+ /*
+ * Assume that HE implies VHT implies 80 MHz at least,
+ * DBE doesn't exist on 2.4 GHz and the capability
+ * shouldn't be set by the driver.
+ *
+ * It's also not very relevant if DBE isn't enabled.
+ */
+ u8 dbe_bw = IEEE80211_UHR_DBE_CAP_MAX_BW_80MHZ;
+
+ if (he_cap->phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
+ HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G)
+ dbe_bw = IEEE80211_UHR_DBE_CAP_MAX_BW_160MHZ;
+
+ if (is_6ghz_op_class(hapd->iconf->op_class) &&
+ eht_cap->phy_cap[EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_IDX] &
+ EHT_PHYCAP_320MHZ_IN_6GHZ_SUPPORT_MASK)
+ dbe_bw = IEEE80211_UHR_DBE_CAP_MAX_BW_320MHZ;
+
+ /*
+ * No MCS maps or other further DBE capabilities
+ * since we just use EHT capabilities and advertise
+ * full EHT capabilities even if operating in a
+ * lower bandwidth.
+ */
+ *pos++ = dbe_bw;
+ }
+
*length_pos = pos - (eid + 2);
return pos;
}
diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h
index 7ec295e5a248..8b32e95e227d 100644
--- a/src/common/ieee802_11_defs.h
+++ b/src/common/ieee802_11_defs.h
@@ -3297,12 +3297,21 @@ struct ieee80211_s1g_beacon_compat {
le32 tsf_completion;
} STRUCT_PACKED;
+#define IEEE80211_UHR_MAC_CAP1_DBE_SUPP 0x04
+
+#define IEEE80211_UHR_DBE_CAP_MAX_BW_MASK 0x07
+#define IEEE80211_UHR_DBE_CAP_MAX_BW_40MHZ 1
+#define IEEE80211_UHR_DBE_CAP_MAX_BW_80MHZ 2
+#define IEEE80211_UHR_DBE_CAP_MAX_BW_160MHZ 3
+#define IEEE80211_UHR_DBE_CAP_MAX_BW_320MHZ 4
+
/* UHR Capabilities element format */
struct ieee80211_uhr_capabilities {
/* UHR MAC Capabilities Information */
u8 mac[5];
/* UHR PHY Capabilities Information */
u8 phy[1];
+ /* followed by DBE capabilities on AP */
} STRUCT_PACKED;
#define UHR_OPER_PARAMS_DPS_ENA 0x0001
--
2.53.0
More information about the Hostap
mailing list