diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c index 1929d6488..c0e5cff5a 100644 --- a/src/ap/ieee802_11.c +++ b/src/ap/ieee802_11.c @@ -7297,6 +7297,77 @@ static u8 * hostapd_eid_wb_channel_switch(struct hostapd_data *hapd, u8 *eid, } +#ifdef CONFIG_IEEE80211BE +/* Bandwidth Indication element that is also used as the Bandwidth Indication + * For Channel Switch subelement within a Channel Switch Wrapper element. */ +static u8 * hostapd_eid_bw_indication(struct hostapd_data *hapd, u8 *eid, + u8 chan1, u8 chan2) +{ + u16 punct_bitmap = hostapd_get_punct_bitmap(hapd); + struct ieee80211_bw_ind_element *bw_ind_elem; + size_t elen = 3; + + if (hapd->cs_freq_params.bandwidth <= 160 && !punct_bitmap) + return eid; + + if (punct_bitmap) + elen += EHT_OPER_DISABLED_SUBCHAN_BITMAP_SIZE; + + *eid++ = WLAN_EID_EXTENSION; + *eid++ = 1 + elen; + *eid++ = WLAN_EID_EXT_BANDWIDTH_INDICATION; + + bw_ind_elem = (struct ieee80211_bw_ind_element *) eid; + os_memset(bw_ind_elem, 0, sizeof(struct ieee80211_bw_ind_element)); + + switch (hapd->cs_freq_params.bandwidth) { + case 320: + bw_ind_elem->bw_ind_info.control |= BW_IND_CHANNEL_WIDTH_320MHZ; + chan2 = chan1; + if (hapd->cs_freq_params.channel < chan1) + chan1 -= 16; + else + chan1 += 16; + break; + case 160: + bw_ind_elem->bw_ind_info.control |= BW_IND_CHANNEL_WIDTH_160MHZ; + chan2 = chan1; + if (hapd->cs_freq_params.channel < chan1) + chan1 -= 8; + else + chan1 += 8; + break; + case 80: + bw_ind_elem->bw_ind_info.control |= BW_IND_CHANNEL_WIDTH_80MHZ; + break; + case 40: + if (hapd->cs_freq_params.sec_channel_offset == 1) + bw_ind_elem->bw_ind_info.control |= + BW_IND_CHANNEL_WIDTH_40MHZ; + else + bw_ind_elem->bw_ind_info.control |= + BW_IND_CHANNEL_WIDTH_20MHZ; + break; + default: + bw_ind_elem->bw_ind_info.control |= BW_IND_CHANNEL_WIDTH_20MHZ; + break; + } + + bw_ind_elem->bw_ind_info.ccfs0 = chan1; + bw_ind_elem->bw_ind_info.ccfs1 = chan2; + + if (punct_bitmap) { + bw_ind_elem->bw_ind_params |= + BW_IND_PARAMETER_DISABLED_SUBCHAN_BITMAP_PRESENT; + bw_ind_elem->bw_ind_info.disabled_chan_bitmap = + host_to_le16(punct_bitmap); + } + + return eid + elen; +} +#endif /* CONFIG_IEEE80211BE */ + + u8 * hostapd_eid_chsw_wrapper(struct hostapd_data *hapd, u8 *eid) { u8 chan1 = 0, chan2 = 0; @@ -7326,6 +7397,13 @@ u8 * hostapd_eid_chsw_wrapper(struct hostapd_data *hapd, u8 *eid) eid = hostapd_eid_wb_channel_switch(hapd, eid, chan1, chan2); +#ifdef CONFIG_IEEE80211BE + if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) { + /* Bandwidth Indication For Channel Switch subelement */ + eid = hostapd_eid_bw_indication(hapd, eid, chan1, chan2); + } +#endif /* CONFIG_IEEE80211BE */ + *eid_len_offset = (eid - eid_len_offset) - 1; return eid; } diff --git a/src/common/ieee802_11_defs.h b/src/common/ieee802_11_defs.h index 7f88fca06..2dee16bd4 100644 --- a/src/common/ieee802_11_defs.h +++ b/src/common/ieee802_11_defs.h @@ -525,6 +525,7 @@ #define WLAN_EID_EXT_MULTI_LINK_TRAFFIC_INDICATION 110 #define WLAN_EID_EXT_QOS_CHARACTERISTICS 113 #define WLAN_EID_EXT_AKM_SUITE_SELECTOR 114 +#define WLAN_EID_EXT_BANDWIDTH_INDICATION 135 /* Extended Capabilities field */ #define WLAN_EXT_CAPAB_20_40_COEX 0 @@ -2872,6 +2873,33 @@ enum ieee80211_eht_ml_sub_elem { EHT_ML_SUB_ELEM_FRAGMENT = 254, }; +/* IEEE P802.11be/D7.0, 9.4.2.329 (Bandwidth Indication element) defines the + * Bandwidth Indication Information field to have the same definition as the + * EHT Operation Information field in the EHT Operation element. + */ +struct ieee80211_bw_ind_info { + u8 control; /* B0..B2: Channel Width */ + u8 ccfs0; + u8 ccfs1; + le16 disabled_chan_bitmap; /* 0 or 2 octets */ +} STRUCT_PACKED; + +/* Control subfield: Channel Width subfield; see Table 9-417e (Channel width, + * CCFS0, and CCFS1 subfields) in IEEE P802.11be/D7.0. */ +#define BW_IND_CHANNEL_WIDTH_20MHZ EHT_OPER_CHANNEL_WIDTH_20MHZ +#define BW_IND_CHANNEL_WIDTH_40MHZ EHT_OPER_CHANNEL_WIDTH_40MHZ +#define BW_IND_CHANNEL_WIDTH_80MHZ EHT_OPER_CHANNEL_WIDTH_80MHZ +#define BW_IND_CHANNEL_WIDTH_160MHZ EHT_OPER_CHANNEL_WIDTH_160MHZ +#define BW_IND_CHANNEL_WIDTH_320MHZ EHT_OPER_CHANNEL_WIDTH_320MHZ + +/* IEEE P802.11be/D7.0, 9.4.2.329 (Bandwidth Indication element) */ +struct ieee80211_bw_ind_element { + u8 bw_ind_params; /* Bandwidth Indication Parameters */ + struct ieee80211_bw_ind_info bw_ind_info; /* 3 or 5 octets */ +} STRUCT_PACKED; + +#define BW_IND_PARAMETER_DISABLED_SUBCHAN_BITMAP_PRESENT BIT(1) + /* IEEE P802.11ay/D4.0, 9.4.2.251 - EDMG Operation element */ #define EDMG_BSS_OPERATING_CHANNELS_OFFSET 6 #define EDMG_OPERATING_CHANNEL_WIDTH_OFFSET 7