]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
hostapd: Add Bandwidth Indication subelement support for channel switch
authorKarthik M <quic_karm@quicinc.com>
Tue, 16 Jul 2024 10:14:06 +0000 (15:44 +0530)
committerJouni Malinen <j@w1.fi>
Tue, 6 Aug 2024 20:15:58 +0000 (23:15 +0300)
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>
src/ap/ieee802_11.c
src/common/ieee802_11_defs.h

index 1929d64880ba5c4fe82278d09f8823605992fee8..c0e5cff5a00578ec12f6442fae5f52725823bac9 100644 (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;
 }
index 7f88fca06e3227cea59cacc430ede1de0bd35385..2dee16bd4cc529cc53d0f608a68b2989c597f666 100644 (file)
 #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