diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 0b4a66ad7..154687d30 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -4998,6 +4998,7 @@ static const struct global_parse_data global_fields[] = { { INT(p2p_device_random_mac_addr), 0 }, { FUNC(p2p_device_persistent_mac_addr), 0 }, { INT(p2p_interface_random_mac_addr), 0 }, + { INT(p2p_6ghz_disable), 0 }, #endif /* CONFIG_P2P */ { FUNC(country), CFG_CHANGED_COUNTRY }, { INT(bss_max_count), 0 }, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index a385da528..3c38e1e57 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -779,6 +779,8 @@ struct wpa_config { int p2p_ignore_shared_freq; int p2p_optimize_listen_chan; + int p2p_6ghz_disable; + struct wpabuf *wps_vendor_ext_m1; #define MAX_WPS_VENDOR_EXT 10 diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 1ca254813..da3b8a958 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -1333,6 +1333,10 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) if (config->p2p_go_freq_change_policy != DEFAULT_P2P_GO_FREQ_MOVE) fprintf(f, "p2p_go_freq_change_policy=%u\n", config->p2p_go_freq_change_policy); + + if (config->p2p_6ghz_disable) + fprintf(f, "p2p_6ghz_disable=%d\n", config->p2p_6ghz_disable); + if (WPA_GET_BE32(config->ip_addr_go)) fprintf(f, "ip_addr_go=%u.%u.%u.%u\n", config->ip_addr_go[0], config->ip_addr_go[1], diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 1fbe15a5b..479fa2fad 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -291,6 +291,41 @@ static void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s, } +static int wpas_p2p_add_scan_freq_list(struct wpa_supplicant *wpa_s, + enum hostapd_hw_mode band, + struct wpa_driver_scan_params *params) +{ + struct hostapd_hw_modes *mode; + int num_chans = 0; + int *freqs, i; + + mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band, 0); + if (!mode) + return -1; + + if (params->freqs) { + while (params->freqs[num_chans]) + num_chans++; + } + + freqs = os_realloc(params->freqs, + (num_chans + mode->num_channels + 1) * sizeof(int)); + if (!freqs) + return -1; + + params->freqs = freqs; + + for (i = 0; i < mode->num_channels; i++) { + if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED) + continue; + params->freqs[num_chans++] = mode->channels[i].freq; + } + params->freqs[num_chans] = 0; + + return 0; +} + + static void wpas_p2p_trigger_scan_cb(struct wpa_radio_work *work, int deinit) { struct wpa_supplicant *wpa_s = work->wpa_s; @@ -312,6 +347,15 @@ static void wpas_p2p_trigger_scan_cb(struct wpa_radio_work *work, int deinit) "Request driver to clear scan cache due to local BSS flush"); params->only_new_results = 1; } + + if (wpa_s->conf->p2p_6ghz_disable && !params->freqs) { + wpa_printf(MSG_DEBUG, + "P2P: 6 GHz disabled - update the scan frequency list"); + wpas_p2p_add_scan_freq_list(wpa_s, HOSTAPD_MODE_IEEE80211G, + params); + wpas_p2p_add_scan_freq_list(wpa_s, HOSTAPD_MODE_IEEE80211A, + params); + } ret = wpa_drv_scan(wpa_s, params); if (ret == 0) wpa_s->curr_scan_cookie = params->scan_cookie; @@ -3726,7 +3770,9 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s, u8 ch; struct p2p_reg_class *reg = NULL, *cli_reg = NULL; - if (o->p2p == NO_P2P_SUPP) + if (o->p2p == NO_P2P_SUPP || + (is_6ghz_op_class(o->op_class) && + wpa_s->conf->p2p_6ghz_disable)) continue; mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, o->mode, @@ -3804,7 +3850,9 @@ int wpas_p2p_get_ht40_mode(struct wpa_supplicant *wpa_s, const struct oper_class_map *o = &global_op_class[op]; u8 ch; - if (o->p2p == NO_P2P_SUPP) + if (o->p2p == NO_P2P_SUPP || + (is_6ghz_op_class(o->op_class) && + wpa_s->conf->p2p_6ghz_disable)) continue; for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) { @@ -5275,6 +5323,13 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq, if (freq > 0) { freqs[0] = freq; params.freqs = freqs; + } else if (wpa_s->conf->p2p_6ghz_disable) { + wpa_printf(MSG_DEBUG, + "P2P: 6 GHz disabled - update the scan frequency list"); + wpas_p2p_add_scan_freq_list(wpa_s, HOSTAPD_MODE_IEEE80211G, + ¶ms); + wpas_p2p_add_scan_freq_list(wpa_s, HOSTAPD_MODE_IEEE80211A, + ¶ms); } ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p); @@ -5305,6 +5360,8 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq, * the new scan results become available. */ ret = wpa_drv_scan(wpa_s, ¶ms); + if (wpa_s->conf->p2p_6ghz_disable && params.freqs != freqs) + os_free(params.freqs); if (!ret) { os_get_reltime(&wpa_s->scan_trigger_time); wpa_s->scan_res_handler = wpas_p2p_scan_res_join; @@ -5645,6 +5702,9 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, return -1; } + if (is_6ghz_freq(freq) && wpa_s->conf->p2p_6ghz_disable) + return -2; + os_free(wpa_s->global->add_psk); wpa_s->global->add_psk = NULL;