P2P: Allow connection on 6 GHz channels if requested

Previously, 6 GHz channels were disabled for P2P operations. Use the new
allow_6ghz parameter with P2P_CONNECT, P2P_GROUP_ADD, and P2P_INVITE
commands for P2P connection on the 6 GHz channels when Wi-Fi Display is
enabled on both the devices.

However, the p2p_6ghz_disable parameter in the configuration takes a
higher precedence.

Indicate P2P 6 GHz band capable information in Device Capability Bitmap
of P2P Capability attribute to indicate the P2P Device is capable of P2P
operation in the 6 GHz band.

Signed-off-by: Sreeramya Soratkal <ssramya@codeaurora.org>
This commit is contained in:
Sreeramya Soratkal 2021-05-04 13:01:49 +05:30 committed by Jouni Malinen
parent b36142a740
commit f0cdacacb3
5 changed files with 86 additions and 9 deletions

View file

@ -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_ht40[] = { 126, 127, 116, 117, 0 };
const int op_classes_vht[] = { 128, 0 }; const int op_classes_vht[] = { 128, 0 };
const int op_classes_edmg[] = { 181, 182, 183, 0 }; const int op_classes_edmg[] = { 181, 182, 183, 0 };
const int op_classes_6ghz[] = { 131, 0 };
p2p_dbg(p2p, "Prepare channel best"); p2p_dbg(p2p, "Prepare channel best");
@ -1448,6 +1449,12 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
0) { 0) {
p2p_dbg(p2p, "Select possible EDMG channel (op_class %u channel %u) as operating channel preference", p2p_dbg(p2p, "Select possible EDMG channel (op_class %u channel %u) as operating channel preference",
p2p->op_reg_class, p2p->op_channel); 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, } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_vht,
&p2p->op_reg_class, &p2p->op_channel) == &p2p->op_reg_class, &p2p->op_channel) ==
0) { 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 p2p_dbg(p2p, "Request to start group negotiation - peer=" MACSTR
" GO Intent=%d Intended Interface Address=" MACSTR " GO Intent=%d Intended Interface Address=" MACSTR
" wps_method=%d persistent_group=%d pd_before_go_neg=%d " " 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), 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); dev = p2p_get_device(p2p, peer_addr);
if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { 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 p2p_dbg(p2p, "Request to authorize group negotiation - peer=" MACSTR
" GO Intent=%d Intended Interface Address=" 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), 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); dev = p2p_get_device(p2p, peer_addr);
if (dev == NULL) { if (dev == NULL) {

View file

@ -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 p2p_wfd_enabled(struct p2p_data *p2p);
bool is_p2p_allow_6ghz(struct p2p_data *p2p); bool is_p2p_allow_6ghz(struct p2p_data *p2p);
void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value); 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 */ #endif /* P2P_H */

View file

@ -653,8 +653,9 @@ int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role,
struct p2p_device *dev; struct p2p_device *dev;
p2p_dbg(p2p, "Request to invite peer " MACSTR " role=%d persistent=%d " p2p_dbg(p2p, "Request to invite peer " MACSTR " role=%d persistent=%d "
"force_freq=%u", "force_freq=%u allow_6ghz=%d",
MAC2STR(peer), role, persistent_group, force_freq); MAC2STR(peer), role, persistent_group, force_freq,
p2p->allow_6ghz);
if (bssid) if (bssid)
p2p_dbg(p2p, "Invitation for BSSID " MACSTR, MAC2STR(bssid)); p2p_dbg(p2p, "Invitation for BSSID " MACSTR, MAC2STR(bssid));
if (go_dev_addr) { if (go_dev_addr) {

View file

@ -517,3 +517,21 @@ void p2p_copy_channels(struct p2p_channels *dst,
} }
dst->reg_classes = j; 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;
}

View file

@ -5424,7 +5424,8 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
if (freq > 0) { if (freq > 0) {
freqs[0] = freq; freqs[0] = freq;
params.freqs = freqs; 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, wpa_printf(MSG_DEBUG,
"P2P: 6 GHz disabled - update the scan frequency list"); "P2P: 6 GHz disabled - update the scan frequency list");
wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, &params, wpa_add_scan_freqs_list(wpa_s, HOSTAPD_MODE_IEEE80211G, &params,
@ -5461,7 +5462,7 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
* the new scan results become available. * the new scan results become available.
*/ */
ret = wpa_drv_scan(wpa_s, &params); ret = wpa_drv_scan(wpa_s, &params);
if (wpa_s->conf->p2p_6ghz_disable && params.freqs != freqs) if (params.freqs != freqs)
os_free(params.freqs); os_free(params.freqs);
if (!ret) { if (!ret) {
os_get_reltime(&wpa_s->scan_trigger_time); 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, res = wpa_drv_get_pref_freq_list(wpa_s, iface_type,
&max_pref_freq, &max_pref_freq,
pref_freq_list); 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) { if (!res && max_pref_freq > 0) {
*num_pref_freq = max_pref_freq; *num_pref_freq = max_pref_freq;
i = 0; 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 * wpas_p2p_connect - Request P2P Group Formation to be started
* @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() * @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; 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; return -2;
os_free(wpa_s->global->add_psk); 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, res = wpa_drv_get_pref_freq_list(wpa_s, WPA_IF_P2P_GO,
&size, pref_freq_list); &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) { if (!res && size > 0) {
i = 0; i = 0;
while (i < size && 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) if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return -1; return -1;
if (wpas_p2p_check_6ghz(wpa_s, NULL, allow_6ghz, freq))
return -1;
os_free(wpa_s->global->add_psk); os_free(wpa_s->global->add_psk);
wpa_s->global->add_psk = NULL; 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; int no_pref_freq_given = pref_freq == 0;
unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size; 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; wpa_s->global->p2p_invite_group = NULL;
if (peer_addr) if (peer_addr)
os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN); 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) if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return -1; return -1;
if (wpas_p2p_check_6ghz(wpa_s, peer_addr, allow_6ghz, freq))
return -1;
size = P2P_MAX_PREF_CHANNELS; size = P2P_MAX_PREF_CHANNELS;
res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq, res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,