diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 88cdd4eab..9ac505735 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -1412,6 +1412,7 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p) const int op_classes_ht40[] = { 126, 127, 116, 117, 0 }; const int op_classes_vht[] = { 128, 0 }; const int op_classes_edmg[] = { 181, 182, 183, 0 }; + const int op_classes_6ghz[] = { 131, 0 }; p2p_dbg(p2p, "Prepare channel best"); @@ -1448,6 +1449,12 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p) 0) { p2p_dbg(p2p, "Select possible EDMG channel (op_class %u channel %u) as operating channel preference", p2p->op_reg_class, p2p->op_channel); + } else if (p2p->allow_6ghz && + (p2p_channel_select(&p2p->cfg->channels, op_classes_6ghz, + &p2p->op_reg_class, &p2p->op_channel) == + 0)) { + p2p_dbg(p2p, "Select possible 6 GHz channel (op_class %u channel %u) as operating channel preference", + p2p->op_reg_class, p2p->op_channel); } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_vht, &p2p->op_reg_class, &p2p->op_channel) == 0) { @@ -1568,9 +1575,10 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, p2p_dbg(p2p, "Request to start group negotiation - peer=" MACSTR " GO Intent=%d Intended Interface Address=" MACSTR " wps_method=%d persistent_group=%d pd_before_go_neg=%d " - "oob_pw_id=%u", + "oob_pw_id=%u allow_6ghz=%d", MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), - wps_method, persistent_group, pd_before_go_neg, oob_pw_id); + wps_method, persistent_group, pd_before_go_neg, oob_pw_id, + p2p->allow_6ghz); dev = p2p_get_device(p2p, peer_addr); if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { @@ -1668,9 +1676,9 @@ int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, p2p_dbg(p2p, "Request to authorize group negotiation - peer=" MACSTR " GO Intent=%d Intended Interface Address=" MACSTR - " wps_method=%d persistent_group=%d oob_pw_id=%u", + " wps_method=%d persistent_group=%d oob_pw_id=%u allow_6ghz=%d", MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), - wps_method, persistent_group, oob_pw_id); + wps_method, persistent_group, oob_pw_id, p2p->allow_6ghz); dev = p2p_get_device(p2p, peer_addr); if (dev == NULL) { diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 4c6e8afef..f606fbb14 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -2422,5 +2422,6 @@ bool p2p_peer_wfd_enabled(struct p2p_data *p2p, const u8 *peer_addr); bool p2p_wfd_enabled(struct p2p_data *p2p); bool is_p2p_allow_6ghz(struct p2p_data *p2p); void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value); +int p2p_remove_6ghz_channels(unsigned int *pref_freq_list, int size); #endif /* P2P_H */ diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c index 77d662a47..ab0072219 100644 --- a/src/p2p/p2p_invitation.c +++ b/src/p2p/p2p_invitation.c @@ -653,8 +653,9 @@ int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role, struct p2p_device *dev; p2p_dbg(p2p, "Request to invite peer " MACSTR " role=%d persistent=%d " - "force_freq=%u", - MAC2STR(peer), role, persistent_group, force_freq); + "force_freq=%u allow_6ghz=%d", + MAC2STR(peer), role, persistent_group, force_freq, + p2p->allow_6ghz); if (bssid) p2p_dbg(p2p, "Invitation for BSSID " MACSTR, MAC2STR(bssid)); if (go_dev_addr) { diff --git a/src/p2p/p2p_utils.c b/src/p2p/p2p_utils.c index 06ab79920..7d21f6881 100644 --- a/src/p2p/p2p_utils.c +++ b/src/p2p/p2p_utils.c @@ -517,3 +517,21 @@ void p2p_copy_channels(struct p2p_channels *dst, } dst->reg_classes = j; } + + +int p2p_remove_6ghz_channels(unsigned int *pref_freq_list, int size) +{ + int i; + + for (i = 0; i < size; i++) { + if (is_6ghz_freq(pref_freq_list[i])) { + wpa_printf(MSG_DEBUG, "P2P: Remove 6 GHz channel %d", + pref_freq_list[i]); + size--; + os_memmove(&pref_freq_list[i], &pref_freq_list[i + 1], + (size - i) * sizeof(pref_freq_list[0])); + i--; + } + } + return i; +} diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index b950a648e..74acb1d43 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -5424,7 +5424,8 @@ 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) { + } else if (wpa_s->conf->p2p_6ghz_disable || + !is_p2p_allow_6ghz(wpa_s->global->p2p)) { wpa_printf(MSG_DEBUG, "P2P: 6 GHz disabled - update the scan frequency list"); wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, ¶ms, @@ -5461,7 +5462,7 @@ 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) + if (params.freqs != freqs) os_free(params.freqs); if (!ret) { os_get_reltime(&wpa_s->scan_trigger_time); @@ -5691,6 +5692,10 @@ static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq, res = wpa_drv_get_pref_freq_list(wpa_s, iface_type, &max_pref_freq, pref_freq_list); + if (!is_p2p_allow_6ghz(wpa_s->global->p2p)) + max_pref_freq = p2p_remove_6ghz_channels(pref_freq_list, + max_pref_freq); + if (!res && max_pref_freq > 0) { *num_pref_freq = max_pref_freq; i = 0; @@ -5750,6 +5755,40 @@ exit_free: } +static bool is_p2p_6ghz_supported(struct wpa_supplicant *wpa_s, + const u8 *peer_addr) +{ + if (wpa_s->conf->p2p_6ghz_disable || + !get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, + HOSTAPD_MODE_IEEE80211A, true)) + return false; + + if (!p2p_wfd_enabled(wpa_s->global->p2p)) + return false; + if (peer_addr && !p2p_peer_wfd_enabled(wpa_s->global->p2p, peer_addr)) + return false; + + return true; +} + + +static int wpas_p2p_check_6ghz(struct wpa_supplicant *wpa_s, + const u8 *peer_addr, bool allow_6ghz, int freq) +{ + if (allow_6ghz && is_p2p_6ghz_supported(wpa_s, peer_addr)) { + wpa_printf(MSG_DEBUG, + "P2P: Allow connection on 6 GHz channels"); + p2p_set_6ghz_dev_capab(wpa_s->global->p2p, true); + } else { + if (is_6ghz_freq(freq)) + return -2; + p2p_set_6ghz_dev_capab(wpa_s->global->p2p, false); + } + + return 0; +} + + /** * wpas_p2p_connect - Request P2P Group Formation to be started * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() @@ -5805,7 +5844,7 @@ 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) + if (wpas_p2p_check_6ghz(wpa_s, peer_addr, allow_6ghz, freq)) return -2; os_free(wpa_s->global->add_psk); @@ -6083,6 +6122,9 @@ static int wpas_p2p_select_go_freq(struct wpa_supplicant *wpa_s, int freq) res = wpa_drv_get_pref_freq_list(wpa_s, WPA_IF_P2P_GO, &size, pref_freq_list); + if (!is_p2p_allow_6ghz(wpa_s->global->p2p)) + size = p2p_remove_6ghz_channels(pref_freq_list, size); + if (!res && size > 0) { i = 0; while (i < size && @@ -6711,6 +6753,8 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) return -1; + if (wpas_p2p_check_6ghz(wpa_s, NULL, allow_6ghz, freq)) + return -1; os_free(wpa_s->global->add_psk); wpa_s->global->add_psk = NULL; @@ -7448,6 +7492,9 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, int no_pref_freq_given = pref_freq == 0; unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size; + if (wpas_p2p_check_6ghz(wpa_s, NULL, allow_6ghz, freq)) + return -1; + wpa_s->global->p2p_invite_group = NULL; if (peer_addr) os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN); @@ -7586,6 +7633,8 @@ int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname, if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) return -1; + if (wpas_p2p_check_6ghz(wpa_s, peer_addr, allow_6ghz, freq)) + return -1; size = P2P_MAX_PREF_CHANNELS; res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,