From: Karthik M Date: Tue, 16 Jul 2024 10:14:06 +0000 (+0530) Subject: hostapd: Add Bandwidth Indication subelement support for channel switch X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c7e704bdf9c357b00a3d94f26090c30c3a0786dd;p=thirdparty%2Fhostap.git hostapd: Add Bandwidth Indication subelement support for channel switch The Bandwidth Indication subelement contains channel bandwidth, channel center frequency, and optionally punctured subchannels. As per IEEE P802.11be/D7.0, 35.15.3 (Channel switching methods for an EHT BSS), if a Channel Switch Announcement element or an Extended Channel Switch Announcement element is used to announce a switch to an EHT BSS operating channel width wider than 160 MHz or to an EHT BSS operating channel width including at least one punctured 20 MHz subchannel, the Bandwidth Indication subelement in the Channel Switch Wrapper element shall be present in the same frame. Hence, add it into the Beacon and Probe Response frames under the above mentioned conditions. Signed-off-by: Karthik M Signed-off-by: Aditya Kumar Singh --- 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