Add Wide Bandwidth Channel Switch element
authorAndrei Otcheretianski <andrei.otcheretianski@intel.com>
Tue, 8 Sep 2015 09:46:12 +0000 (12:46 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 3 Oct 2015 16:40:46 +0000 (19:40 +0300)
When switching to a VHT channel with width greater than 20 MHz, add Wide
Bandwidth Channel Switch element. This element is added in Beacon and
Probe Response frames inside Channel Switch Wrapper element.

Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com>
src/ap/beacon.c
src/ap/ieee802_11.h
src/ap/ieee802_11_vht.c

index cdca8a3..ea6b009 100644 (file)
@@ -347,6 +347,9 @@ static u8 * hostapd_add_csa_elems(struct hostapd_data *hapd, u8 *pos,
                /* save an offset to the counter - should be last byte */
                *csa_counter_off = pos - start - 1;
                pos = hostapd_eid_secondary_channel(hapd, pos);
+#ifdef CONFIG_IEEE80211AC
+               pos = hostapd_eid_wb_chsw_wrapper(hapd, pos);
+#endif /* CONFIG_IEEE80211AC */
        }
 
        return pos;
index 44c1bff..2c18f2b 100644 (file)
@@ -52,6 +52,8 @@ u8 * hostapd_eid_ht_operation(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_vht_capabilities(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_vht_operation(struct hostapd_data *hapd, u8 *eid);
 u8 * hostapd_eid_vendor_vht(struct hostapd_data *hapd, u8 *eid);
+u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid);
+
 int hostapd_ht_operation_update(struct hostapd_iface *iface);
 void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
                                  const u8 *addr, const u8 *trans_id);
index 5bf1b5d..6fda289 100644 (file)
@@ -131,6 +131,58 @@ static int check_valid_vht_mcs(struct hostapd_hw_modes *mode,
 }
 
 
+u8 * hostapd_eid_wb_chsw_wrapper(struct hostapd_data *hapd, u8 *eid)
+{
+       u8 bw, chan1, chan2 = 0;
+       int freq1;
+
+       if (!hapd->cs_freq_params.vht_enabled)
+               return eid;
+
+       /* bandwidth: 0: 40, 1: 80, 2: 160, 3: 80+80 */
+       switch (hapd->cs_freq_params.bandwidth) {
+       case 40:
+               bw = 0;
+               break;
+       case 80:
+               /* check if it's 80+80 */
+               if (!hapd->cs_freq_params.center_freq2)
+                       bw = 1;
+               else
+                       bw = 3;
+               break;
+       case 160:
+               bw = 2;
+               break;
+       default:
+               /* not valid VHT bandwidth or not in CSA */
+               return eid;
+       }
+
+       freq1 = hapd->cs_freq_params.center_freq1 ?
+               hapd->cs_freq_params.center_freq1 :
+               hapd->cs_freq_params.freq;
+       if (ieee80211_freq_to_chan(freq1, &chan1) !=
+           HOSTAPD_MODE_IEEE80211A)
+               return eid;
+
+       if (hapd->cs_freq_params.center_freq2 &&
+           ieee80211_freq_to_chan(hapd->cs_freq_params.center_freq2,
+                                  &chan2) != HOSTAPD_MODE_IEEE80211A)
+               return eid;
+
+       *eid++ = WLAN_EID_VHT_CHANNEL_SWITCH_WRAPPER;
+       *eid++ = 5; /* Length of Channel Switch Wrapper */
+       *eid++ = WLAN_EID_VHT_WIDE_BW_CHSWITCH;
+       *eid++ = 3; /* Length of Wide Bandwidth Channel Switch element */
+       *eid++ = bw; /* New Channel Width */
+       *eid++ = chan1; /* New Channel Center Frequency Segment 0 */
+       *eid++ = chan2; /* New Channel Center Frequency Segment 1 */
+
+       return eid;
+}
+
+
 u16 copy_sta_vht_capab(struct hostapd_data *hapd, struct sta_info *sta,
                       const u8 *vht_capab)
 {