}
+#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;
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;
}
#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
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