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 <quic_karm@quicinc.com>
Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com>
This commit is contained in:
Karthik M 2024-07-16 15:44:06 +05:30 committed by Jouni Malinen
parent c9d0c6fd7e
commit c7e704bdf9
2 changed files with 106 additions and 0 deletions

View file

@ -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;
}

View file

@ -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