aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/config.c1
-rw-r--r--wpa_supplicant/config.h8
-rw-r--r--wpa_supplicant/config_file.c2
-rw-r--r--wpa_supplicant/ctrl_iface.c3
-rw-r--r--wpa_supplicant/p2p_supplicant.c68
-rw-r--r--wpa_supplicant/wpa_supplicant_template.conf2
6 files changed, 77 insertions, 7 deletions
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 8bae7b7..69eb7d0 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2995,6 +2995,7 @@ static const struct global_parse_data global_fields[] = {
{ BIN(wps_nfc_dev_pw), 0 },
{ INT(p2p_go_max_inactivity), 0 },
{ INT(p2p_go_ht40), 0 },
+ { INT(p2p_multi_chan), 0 },
{ INT_RANGE(sched_scan_num_short_intervals, 0,
MAX_NUM_SCHED_SCAN_SHORT_INTERVALS), 0 },
{ INT_RANGE(sched_scan_short_interval, 1, MAX_SCHED_SCAN_INTERVAL), 0 },
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index 568af0d..eb7dbf0 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -702,6 +702,14 @@ struct wpa_config {
int p2p_go_ht40;
/**
+ * p2p_multi_chan - Default to multi-channel operation when operating
+ * as p2p. We will try to optimize throughput instead of trying to make
+ * sure P2P starts on the same channel as another interface that's
+ * currently connected.
+ */
+ int p2p_multi_chan;
+
+ /**
* sched_scan_short_interval - Initial interval for sched scan in secs
* sched scan will start with this interval for num_short_intervals
* intervals and then switch to a longer interval defined by
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index 32c6990..cbece8e 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -898,6 +898,8 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
config->p2p_go_max_inactivity);
if (config->p2p_go_ht40)
fprintf(f, "p2p_go_ht40=%u\n", config->p2p_go_ht40);
+ if (config->p2p_multi_chan)
+ fprintf(f, "p2p_multi_chan=%u\n", config->p2p_multi_chan);
if (config->sched_scan_num_short_intervals !=
DEFAULT_SCHED_SCAN_NUM_SHORT_INTERVALS)
fprintf(f, "sched_scan_num_short_intervals=%u\n",
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 2fdd535..8aad951 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -2974,6 +2974,9 @@ int p2p_handle_concurrency_conflicts(struct wpa_supplicant *wpa_s, int *go_inten
struct wpa_supplicant *iface = NULL;
struct p2p_data *p2p = wpa_s->global->p2p;
+ if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)
+ return 0;
+
wpa_printf(MSG_INFO, "p2p: handling concurrency conflicts");
/* we only fear frequency conflicts */
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 89bd5ae..b0eb594 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -3264,13 +3264,17 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
return ret;
}
- if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid) == 0 &&
- wpa_s->assoc_freq)
- oper_freq = wpa_s->assoc_freq;
- else {
- oper_freq = wpa_drv_shared_freq(wpa_s);
- if (oper_freq < 0)
- oper_freq = 0;
+ if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) ||
+ !wpa_s->conf->p2p_multi_chan) {
+ if (wpa_s->current_ssid &&
+ wpa_drv_get_bssid(wpa_s, bssid) == 0 &&
+ wpa_s->assoc_freq)
+ oper_freq = wpa_s->assoc_freq;
+ else {
+ oper_freq = wpa_drv_shared_freq(wpa_s);
+ if (oper_freq < 0)
+ oper_freq = 0;
+ }
}
if (freq > 0) {
@@ -3965,6 +3969,18 @@ static void wpas_p2p_clear_pending_action_tx(struct wpa_supplicant *wpa_s)
wpa_s->pending_action_tx = NULL;
}
+static int wpas_p2p_connected(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_supplicant *iface;
+
+ for (iface = wpa_s->global->ifaces; iface; iface = iface->next) {
+ if (iface->p2p_group_interface == P2P_GROUP_INTERFACE_GO ||
+ iface->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT)
+ return 1;
+ }
+
+ return 0;
+}
int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
enum p2p_discovery_type type,
@@ -3981,6 +3997,14 @@ int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,
wpa_s->p2p_in_provisioning)
return -1;
+
+ if (!(wpa_s->drv_flags &
+ WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) &&
+ wpas_p2p_connected(wpa_s)) {
+ wpa_printf(MSG_DEBUG, "P2P: find blocked due to active GO/CLI");
+ return -1;
+ }
+
wpa_supplicant_cancel_sched_scan(wpa_s);
return p2p_find(wpa_s->global->p2p, timeout, type,
@@ -4892,6 +4916,24 @@ int wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr)
return p2p_unauthorize(p2p, peer);
}
+int wpas_is_p2p_iface(struct wpa_supplicant *wpa_s)
+{
+ struct wpa_ssid *ssid;
+
+ if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
+ return 1;
+
+ /* P2P GO in case no group iface */
+ if (wpa_s->p2p_group)
+ return 1;
+
+ /* P2P CLI in case no group iface */
+ ssid = wpa_s->current_ssid;
+ if (ssid && ssid->p2p_group)
+ return 1;
+
+ return 0;
+}
/**
* wpas_p2p_disconnect - Disconnect from a P2P Group
@@ -4910,6 +4952,12 @@ int wpas_p2p_disconnect(struct wpa_supplicant *wpa_s)
if (wpa_s == NULL)
return -1;
+ if (!wpas_is_p2p_iface(wpa_s)) {
+ wpa_printf(MSG_DEBUG, "P2P: No group to disconnect on %s",
+ wpa_s->ifname);
+ return -1;
+ }
+
wpa_s->removal_reason = P2P_GROUP_REMOVAL_REQUESTED;
wpas_p2p_group_delete(wpa_s, 0);
@@ -5032,6 +5080,12 @@ int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq)
iface->current_ssid->frequency = freq;
continue;
}
+
+ /* some drivers can handle this on their own */
+ if (wpa_s->driver->hapd_channel_switch) {
+ wpa_printf(MSG_INFO, "P2P: GO Ch. switch will be initiated by the driver");
+ continue;
+ }
}
/*
diff --git a/wpa_supplicant/wpa_supplicant_template.conf b/wpa_supplicant/wpa_supplicant_template.conf
index b9f902b..901209a 100644
--- a/wpa_supplicant/wpa_supplicant_template.conf
+++ b/wpa_supplicant/wpa_supplicant_template.conf
@@ -7,3 +7,5 @@ fast_reauth=1
p2p_conc_mode=2
p2p_go_max_inactivity=30
p2p_go_ht40=1
+p2p_multi_chan=1
+disassoc_low_ack=1