EHT: Add operation element in AP mode Management frames

Add EHT Operation element in Beacon, Probe Response, and (Re)Association
Response frames using the format described in IEEE P802.11be/D1.5,
9.4.2.311.

Signed-off-by: Aloka Dixit <quic_alokad@quicinc.com>
Signed-off-by: Muna Sinada <quic_msinada@quicinc.com>
Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
This commit is contained in:
Aloka Dixit 2022-04-19 11:04:09 -07:00 committed by Jouni Malinen
parent 9b7202d665
commit d54e3d0495
4 changed files with 80 additions and 6 deletions

View file

@ -510,8 +510,10 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
#endif /* CONFIG_IEEE80211AX */
#ifdef CONFIG_IEEE80211BE
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be)
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP);
buflen += 3 + sizeof(struct ieee80211_eht_operation);
}
#endif /* CONFIG_IEEE80211BE */
buflen += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_PROBE_RESP);
@ -641,8 +643,10 @@ static u8 * hostapd_gen_probe_resp(struct hostapd_data *hapd,
#endif /* CONFIG_IEEE80211AX */
#ifdef CONFIG_IEEE80211BE
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be)
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
pos = hostapd_eid_eht_capab(hapd, pos, IEEE80211_MODE_AP);
pos = hostapd_eid_eht_operation(hapd, pos);
}
#endif /* CONFIG_IEEE80211BE */
#ifdef CONFIG_IEEE80211AC
@ -1549,8 +1553,10 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
#endif /* CONFIG_IEEE80211AX */
#ifdef CONFIG_IEEE80211BE
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be)
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
tail_len += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP);
tail_len += 3 + sizeof(struct ieee80211_eht_operation);
}
#endif /* CONFIG_IEEE80211BE */
tail_len += hostapd_eid_rnr_len(hapd, WLAN_FC_STYPE_BEACON);
@ -1701,9 +1707,11 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
#endif /* CONFIG_IEEE80211AX */
#ifdef CONFIG_IEEE80211BE
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be)
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
tailpos = hostapd_eid_eht_capab(hapd, tailpos,
IEEE80211_MODE_AP);
tailpos = hostapd_eid_eht_operation(hapd, tailpos);
}
#endif /* CONFIG_IEEE80211BE */
#ifdef CONFIG_IEEE80211AC

View file

@ -5045,8 +5045,10 @@ static u16 send_assoc_resp(struct hostapd_data *hapd, struct sta_info *sta,
buflen += 5 + sta->dpp_pfs->curve->prime_len;
#endif /* CONFIG_DPP2 */
#ifdef CONFIG_IEEE80211BE
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be)
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
buflen += hostapd_eid_eht_capab_len(hapd, IEEE80211_MODE_AP);
buflen += 3 + sizeof(struct ieee80211_eht_operation);
}
#endif /* CONFIG_IEEE80211BE */
buf = os_zalloc(buflen);
@ -5196,8 +5198,10 @@ rsnxe_done:
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_IEEE80211BE
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be)
if (hapd->iconf->ieee80211be && !hapd->conf->disable_11be) {
p = hostapd_eid_eht_capab(hapd, p, IEEE80211_MODE_AP);
p = hostapd_eid_eht_operation(hapd, p);
}
#endif /* CONFIG_IEEE80211BE */
#ifdef CONFIG_OWE

View file

@ -205,5 +205,6 @@ size_t hostapd_eid_eht_capab_len(struct hostapd_data *hapd,
enum ieee80211_op_mode opmode);
u8 * hostapd_eid_eht_capab(struct hostapd_data *hapd, u8 *eid,
enum ieee80211_op_mode opmode);
u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid);
#endif /* IEEE802_11_H */

View file

@ -155,3 +155,64 @@ u8 * hostapd_eid_eht_capab(struct hostapd_data *hapd, u8 *eid,
*length_pos = pos - (eid + 2);
return pos;
}
u8 * hostapd_eid_eht_operation(struct hostapd_data *hapd, u8 *eid)
{
struct hostapd_config *conf = hapd->iconf;
struct ieee80211_eht_operation *oper;
u8 *pos = eid, chwidth, seg0 = 0, seg1 = 0;
if (!hapd->iface->current_mode)
return eid;
*pos++ = WLAN_EID_EXTENSION;
*pos++ = 5;
*pos++ = WLAN_EID_EXT_EHT_OPERATION;
oper = (struct ieee80211_eht_operation *) pos;
oper->oper_params = EHT_OPER_INFO_PRESENT;
if (is_6ghz_op_class(conf->op_class))
chwidth = op_class_to_ch_width(conf->op_class);
else
chwidth = conf->eht_oper_chwidth;
seg0 = hostapd_get_oper_centr_freq_seg0_idx(conf);
switch (chwidth) {
#if 0 /* FIX: Need to clean up CHANWIDTH_* use for protocol vs. internal
* needs to be able to define this. */
case CHANWIDTH_320MHZ:
oper->oper_info.control |= EHT_OPER_CHANNEL_WIDTH_320MHZ;
seg1 = seg0;
if (hapd->iconf->channel < seg0)
seg0 -= 16;
else
seg0 += 16;
break;
#endif
case CHANWIDTH_160MHZ:
oper->oper_info.control |= EHT_OPER_CHANNEL_WIDTH_160MHZ;
seg1 = seg0;
if (hapd->iconf->channel < seg0)
seg0 -= 8;
else
seg0 += 8;
break;
case CHANWIDTH_80MHZ:
oper->oper_info.control |= EHT_OPER_CHANNEL_WIDTH_80MHZ;
break;
case CHANWIDTH_USE_HT:
if (seg0)
oper->oper_info.control |= EHT_OPER_CHANNEL_WIDTH_40MHZ;
break;
default:
return eid;
}
oper->oper_info.ccfs0 = seg0 ? seg0 : hapd->iconf->channel;
oper->oper_info.ccfs1 = seg1;
return pos + 4;
}