]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
hostapd: Extend Country element to support 6 GHz band
authorPradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
Thu, 7 Apr 2022 23:56:51 +0000 (16:56 -0700)
committerJouni Malinen <j@w1.fi>
Fri, 8 Apr 2022 09:57:46 +0000 (12:57 +0300)
Add support for the Country element for the 6 GHz band per IEEE Std
802.11ax-2021, 9.4.2.8 (Country element).

Signed-off-by: Pradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
src/ap/beacon.c

index 8cd1c417043e7aa181ba87a4bb470680b2db44c9..5ab44f64e15c3541e4ecb77f36cfa7ba5724c5cf 100644 (file)
@@ -186,7 +186,8 @@ static u8 * hostapd_eid_pwr_constraint(struct hostapd_data *hapd, u8 *eid)
 }
 
 
-static u8 * hostapd_eid_country_add(u8 *pos, u8 *end, int chan_spacing,
+static u8 * hostapd_eid_country_add(struct hostapd_data *hapd, u8 *pos,
+                                   u8 *end, int chan_spacing,
                                    struct hostapd_channel_data *start,
                                    struct hostapd_channel_data *prev)
 {
@@ -198,31 +199,23 @@ static u8 * hostapd_eid_country_add(u8 *pos, u8 *end, int chan_spacing,
        /* number of channels */
        *pos++ = (prev->chan - start->chan) / chan_spacing + 1;
        /* maximum transmit power level */
-       *pos++ = start->max_tx_power;
+       if (!is_6ghz_op_class(hapd->iconf->op_class))
+               *pos++ = start->max_tx_power;
+       else
+               *pos++ = 0; /* Reserved when operating on the 6 GHz band */
 
        return pos;
 }
 
 
-static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
-                               int max_len)
+static u8 * hostapd_fill_subband_triplets(struct hostapd_data *hapd, u8 *pos,
+                                           u8 *end)
 {
-       u8 *pos = eid;
-       u8 *end = eid + max_len;
        int i;
        struct hostapd_hw_modes *mode;
        struct hostapd_channel_data *start, *prev;
        int chan_spacing = 1;
 
-       if (!hapd->iconf->ieee80211d || max_len < 6 ||
-           hapd->iface->current_mode == NULL)
-               return eid;
-
-       *pos++ = WLAN_EID_COUNTRY;
-       pos++; /* length will be set later */
-       os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */
-       pos += 3;
-
        mode = hapd->iface->current_mode;
        if (mode->mode == HOSTAPD_MODE_IEEE80211A)
                chan_spacing = 4;
@@ -240,7 +233,8 @@ static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
                }
 
                if (start && prev) {
-                       pos = hostapd_eid_country_add(pos, end, chan_spacing,
+                       pos = hostapd_eid_country_add(hapd, pos, end,
+                                                     chan_spacing,
                                                      start, prev);
                        start = NULL;
                }
@@ -250,10 +244,50 @@ static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
        }
 
        if (start) {
-               pos = hostapd_eid_country_add(pos, end, chan_spacing,
+               pos = hostapd_eid_country_add(hapd, pos, end, chan_spacing,
                                              start, prev);
        }
 
+       return pos;
+}
+
+
+static u8 * hostapd_eid_country(struct hostapd_data *hapd, u8 *eid,
+                               int max_len)
+{
+       u8 *pos = eid;
+       u8 *end = eid + max_len;
+
+       if (!hapd->iconf->ieee80211d || max_len < 6 ||
+           hapd->iface->current_mode == NULL)
+               return eid;
+
+       *pos++ = WLAN_EID_COUNTRY;
+       pos++; /* length will be set later */
+       os_memcpy(pos, hapd->iconf->country, 3); /* e.g., 'US ' */
+       pos += 3;
+
+       if (is_6ghz_op_class(hapd->iconf->op_class)) {
+               /* Force the third octet of the country string to indicate
+                * Global Operating Class (Table E-4) */
+               eid[4] = 0x04;
+
+               /* Operating Triplet field */
+               /* Operating Extension Identifier (>= 201 to indicate this is
+                * not a Subband Triplet field) */
+               *pos++ = 201;
+               /* Operating Class */
+               *pos++ = hapd->iconf->op_class;
+               /* Coverage Class */
+               *pos++ = 0;
+               /* Subband Triplets are required only for the 20 MHz case */
+               if (hapd->iconf->op_class == 131 ||
+                   hapd->iconf->op_class == 136)
+                       pos = hostapd_fill_subband_triplets(hapd, pos, end);
+       } else {
+               pos = hostapd_fill_subband_triplets(hapd, pos, end);
+       }
+
        if ((pos - eid) & 1) {
                if (end - pos < 1)
                        return eid;