]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
EHT: Add operation element in AP mode Management frames
authorAloka Dixit <quic_alokad@quicinc.com>
Tue, 19 Apr 2022 18:04:09 +0000 (11:04 -0700)
committerJouni Malinen <j@w1.fi>
Fri, 29 Apr 2022 14:28:40 +0000 (17:28 +0300)
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>
src/ap/beacon.c
src/ap/ieee802_11.c
src/ap/ieee802_11.h
src/ap/ieee802_11_eht.c

index 270b28b713e5c3459e447ece0f9565d555f1b134..7212f501fe76fc3c1008f337922825404636a069 100644 (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
index c7ee3e126f3c08d29c2a26a35f5b59968c56c025..d4f49330c7ddf6063a57157ce2c7f9c454497045 100644 (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
index b8fcfae0dc1c3c1ac6354590e8c5c44dc4b240a1..79c76284c0c3f10fe4a5bf260a698c9d9b61544b 100644 (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 */
index f4807d081e62a1f1dfcd3a409357f9dd3159050a..fe22d4981d78a14384209d13155f0461ac29965c 100644 (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;
+}