hostapd: Allow ACS to be offloaded to the driver
[mech_eap.git] / src / ap / acs.c
index 60b7580..97cf26f 100644 (file)
@@ -284,6 +284,7 @@ static void acs_fail(struct hostapd_iface *iface)
 {
        wpa_printf(MSG_ERROR, "ACS: Failed to start");
        acs_cleanup(iface);
+       hostapd_disable_iface(iface);
 }
 
 
@@ -638,23 +639,26 @@ acs_find_ideal_chan(struct hostapd_iface *iface)
 
 static void acs_adjust_vht_center_freq(struct hostapd_iface *iface)
 {
+       int offset;
+
        wpa_printf(MSG_DEBUG, "ACS: Adjusting VHT center frequency");
 
        switch (iface->conf->vht_oper_chwidth) {
        case VHT_CHANWIDTH_USE_HT:
-               iface->conf->vht_oper_centr_freq_seg0_idx =
-                       iface->conf->channel + 2;
+               offset = 2 * iface->conf->secondary_channel;
                break;
        case VHT_CHANWIDTH_80MHZ:
-               iface->conf->vht_oper_centr_freq_seg0_idx =
-                       iface->conf->channel + 6;
+               offset = 6;
                break;
        default:
                /* TODO: How can this be calculated? Adjust
                 * acs_find_ideal_chan() */
                wpa_printf(MSG_INFO, "ACS: Only VHT20/40/80 is supported now");
-               break;
+               return;
        }
+
+       iface->conf->vht_oper_centr_freq_seg0_idx =
+               iface->conf->channel + offset;
 }
 
 
@@ -745,7 +749,7 @@ static void acs_scan_complete(struct hostapd_iface *iface)
        err = hostapd_drv_get_survey(iface->bss[0], 0);
        if (err) {
                wpa_printf(MSG_ERROR, "ACS: Failed to get survey data");
-               acs_fail(iface);
+               goto fail;
        }
 
        if (++iface->acs_num_completed_scans < iface->conf->acs_num_scans) {
@@ -797,6 +801,7 @@ static int acs_request_scan(struct hostapd_iface *iface)
        if (hostapd_driver_scan(iface->bss[0], &params) < 0) {
                wpa_printf(MSG_ERROR, "ACS: Failed to request initial scan");
                acs_cleanup(iface);
+               os_free(params.freqs);
                return -1;
        }
 
@@ -811,6 +816,14 @@ enum hostapd_chan_status acs_init(struct hostapd_iface *iface)
 
        wpa_printf(MSG_INFO, "ACS: Automatic channel selection started, this may take a bit");
 
+       if (iface->drv_flags & WPA_DRIVER_FLAGS_ACS_OFFLOAD) {
+               wpa_printf(MSG_INFO, "ACS: Offloading to driver");
+               err = hostapd_drv_do_acs(iface->bss[0]);
+               if (err)
+                       return HOSTAPD_CHAN_INVALID;
+               return HOSTAPD_CHAN_ACS;
+       }
+
        acs_cleanup(iface);
 
        err = acs_request_scan(iface);