P2P: Add support for VHT 80+80 MHz and 160 MHz
authorAhmad Kholaif <akholaif@qca.qualcomm.com>
Wed, 28 Oct 2015 21:14:10 +0000 (14:14 -0700)
committerJouni Malinen <j@w1.fi>
Wed, 25 Nov 2015 17:01:20 +0000 (19:01 +0200)
The new max_oper_chwidth and freq2 arguments to P2P_CONNECT, P2P_INVITE,
and P2P_GROUP_ADD control interface commands can be used to request
larger VHT operating channel bandwidth to be used than the previously
used maximum 80 MHz.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/p2p/p2p.h
wpa_supplicant/ap.c
wpa_supplicant/config_ssid.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/dbus/dbus_new_handlers_p2p.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h
wpa_supplicant/wpa_supplicant_i.h

index fe7f53b..bfdb2c9 100644 (file)
@@ -99,6 +99,10 @@ struct p2p_go_neg_results {
 
        int vht;
 
+       u8 max_oper_chwidth;
+
+       unsigned int vht_center_freq2;
+
        /**
         * ssid - SSID of the group
         */
index cefb3dc..27fa2a9 100644 (file)
@@ -56,12 +56,32 @@ static void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s,
        if (!conf->secondary_channel)
                goto no_vht;
 
-       center_chan = wpas_p2p_get_vht80_center(wpa_s, mode, channel);
+       switch (conf->vht_oper_chwidth) {
+       case VHT_CHANWIDTH_80MHZ:
+       case VHT_CHANWIDTH_80P80MHZ:
+               center_chan = wpas_p2p_get_vht80_center(wpa_s, mode, channel);
+               break;
+       case VHT_CHANWIDTH_160MHZ:
+               center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel);
+               break;
+       default:
+               /*
+                * conf->vht_oper_chwidth might not be set for non-P2P GO cases,
+                * try oper_cwidth 160 MHz first then VHT 80 MHz, if 160 MHz is
+                * not supported.
+                */
+               conf->vht_oper_chwidth = VHT_CHANWIDTH_160MHZ;
+               center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel);
+               if (!center_chan) {
+                       conf->vht_oper_chwidth = VHT_CHANWIDTH_80MHZ;
+                       center_chan = wpas_p2p_get_vht80_center(wpa_s, mode,
+                                                               channel);
+               }
+               break;
+       }
        if (!center_chan)
                goto no_vht;
 
-       /* Use 80 MHz channel */
-       conf->vht_oper_chwidth = 1;
        conf->vht_oper_centr_freq_seg0_idx = center_chan;
        return;
 
@@ -635,6 +655,13 @@ int wpa_supplicant_create_ap(struct wpa_supplicant *wpa_s,
                return -1;
        }
 
+       /* Use the maximum oper channel width if it's given. */
+       if (ssid->max_oper_chwidth)
+               conf->vht_oper_chwidth = ssid->max_oper_chwidth;
+
+       ieee80211_freq_to_chan(ssid->vht_center_freq2,
+                              &conf->vht_oper_centr_freq_seg1_idx);
+
        os_memcpy(wpa_s->ap_iface->conf->wmm_ac_params,
                  wpa_s->conf->wmm_ac_params,
                  sizeof(wpa_s->conf->wmm_ac_params));
index 7ef326c..de8157a 100644 (file)
@@ -449,6 +449,10 @@ struct wpa_ssid {
 
        int vht;
 
+       u8 max_oper_chwidth;
+
+       unsigned int vht_center_freq2;
+
        /**
         * wpa_ptk_rekey - Maximum lifetime for PTK in seconds
         *
index de68f56..9f0025a 100644 (file)
@@ -4861,6 +4861,30 @@ static int p2p_ctrl_asp_provision(struct wpa_supplicant *wpa_s, char *cmd)
 }
 
 
+static int parse_freq(int chwidth, int freq2)
+{
+       if (freq2 < 0)
+               return -1;
+       if (freq2)
+               return VHT_CHANWIDTH_80P80MHZ;
+
+       switch (chwidth) {
+       case 0:
+       case 20:
+       case 40:
+               return VHT_CHANWIDTH_USE_HT;
+       case 80:
+               return VHT_CHANWIDTH_80MHZ;
+       case 160:
+               return VHT_CHANWIDTH_160MHZ;
+       default:
+               wpa_printf(MSG_DEBUG, "Unknown max oper bandwidth: %d",
+                          chwidth);
+               return -1;
+       }
+}
+
+
 static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
                            char *buf, size_t buflen)
 {
@@ -4877,7 +4901,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
        int go_intent = -1;
        int freq = 0;
        int pd;
-       int ht40, vht;
+       int ht40, vht, max_oper_chwidth, chwidth = 0, freq2 = 0;
 
        if (!wpa_s->global->p2p_init_wpa_s)
                return -1;
@@ -4938,6 +4962,18 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
                        return -1;
        }
 
+       pos2 = os_strstr(pos, " freq2=");
+       if (pos2)
+               freq2 = atoi(pos2 + 7);
+
+       pos2 = os_strstr(pos, " max_oper_chwidth=");
+       if (pos2)
+               chwidth = atoi(pos2 + 18);
+
+       max_oper_chwidth = parse_freq(chwidth, freq2);
+       if (max_oper_chwidth < 0)
+               return -1;
+
        if (os_strncmp(pos, "pin", 3) == 0) {
                /* Request random PIN (to be displayed) and enable the PIN */
                wps_method = WPS_PIN_DISPLAY;
@@ -4962,8 +4998,8 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
 
        new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
                                   persistent_group, automatic, join,
-                                  auth, go_intent, freq, persistent_id, pd,
-                                  ht40, vht);
+                                  auth, go_intent, freq, freq2, persistent_id,
+                                  pd, ht40, vht, max_oper_chwidth);
        if (new_pin == -2) {
                os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
                return 25;
@@ -5518,7 +5554,7 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
        struct wpa_ssid *ssid;
        u8 *_peer = NULL, peer[ETH_ALEN];
        int freq = 0, pref_freq = 0;
-       int ht40, vht;
+       int ht40, vht, max_oper_chwidth, chwidth = 0, freq2 = 0;
 
        id = atoi(cmd);
        pos = os_strstr(cmd, " peer=");
@@ -5556,8 +5592,20 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
        ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 ||
                vht;
 
-       return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, ht40, vht,
-                              pref_freq);
+       pos = os_strstr(cmd, "freq2=");
+       if (pos)
+               freq2 = atoi(pos + 6);
+
+       pos = os_strstr(cmd, " max_oper_chwidth=");
+       if (pos)
+               chwidth = atoi(pos + 18);
+
+       max_oper_chwidth = parse_freq(chwidth, freq2);
+       if (max_oper_chwidth < 0)
+               return -1;
+
+       return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, freq2, ht40, vht,
+                              max_oper_chwidth, pref_freq);
 }
 
 
@@ -5604,7 +5652,8 @@ static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd)
 
 
 static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
-                                        int id, int freq, int ht40, int vht)
+                                        int id, int freq, int vht_center_freq2,
+                                        int ht40, int vht, int vht_chwidth)
 {
        struct wpa_ssid *ssid;
 
@@ -5616,8 +5665,9 @@ static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
                return -1;
        }
 
-       return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, ht40, vht,
-                                            NULL, 0, 0);
+       return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq,
+                                            vht_center_freq2, 0, ht40, vht,
+                                            vht_chwidth, NULL, 0, 0);
 }
 
 
@@ -5626,11 +5676,14 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
        int freq = 0, persistent = 0, group_id = -1;
        int vht = wpa_s->conf->p2p_go_vht;
        int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
+       int max_oper_chwidth, chwidth = 0, freq2 = 0;
        char *token, *context = NULL;
 
        while ((token = str_token(cmd, " ", &context))) {
                if (sscanf(token, "freq=%d", &freq) == 1 ||
-                   sscanf(token, "persistent=%d", &group_id) == 1) {
+                   sscanf(token, "freq2=%d", &freq2) == 1 ||
+                   sscanf(token, "persistent=%d", &group_id) == 1 ||
+                   sscanf(token, "max_oper_chwidth=%d", &chwidth) == 1) {
                        continue;
                } else if (os_strcmp(token, "ht40") == 0) {
                        ht40 = 1;
@@ -5647,11 +5700,17 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
                }
        }
 
+       max_oper_chwidth = parse_freq(chwidth, freq2);
+       if (max_oper_chwidth < 0)
+               return -1;
+
        if (group_id >= 0)
                return p2p_ctrl_group_add_persistent(wpa_s, group_id,
-                                                    freq, ht40, vht);
+                                                    freq, freq2, ht40, vht,
+                                                    max_oper_chwidth);
 
-       return wpas_p2p_group_add(wpa_s, persistent, freq, ht40, vht);
+       return wpas_p2p_group_add(wpa_s, persistent, freq, freq2, ht40, vht,
+                                 max_oper_chwidth);
 }
 
 
index c3ec064..a0c5ff7 100644 (file)
@@ -364,13 +364,14 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
                        goto inv_args;
 
                if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, 0,
-                                                 NULL, 0, 0)) {
+                                                 0, 0, NULL, 0, 0)) {
                        reply = wpas_dbus_error_unknown_error(
                                message,
                                "Failed to reinvoke a persistent group");
                        goto out;
                }
-       } else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, 0, 0))
+       } else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, 0, 0, 0,
+                                     0))
                goto inv_args;
 
 out:
@@ -582,7 +583,7 @@ DBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message,
 
        new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
                                   persistent_group, 0, join, authorize_only,
-                                  go_intent, freq, -1, 0, 0, 0);
+                                  go_intent, freq, 0, -1, 0, 0, 0, 0);
 
        if (new_pin >= 0) {
                char npin[9];
@@ -733,8 +734,8 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
                if (ssid == NULL || ssid->disabled != 2)
                        goto err;
 
-               if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0, 0, 0) <
-                   0) {
+               if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0, 0, 0, 0,
+                                   0) < 0) {
                        reply = wpas_dbus_error_unknown_error(
                                message,
                                "Failed to reinvoke a persistent group");
index 020a469..c290a4e 100644 (file)
@@ -1877,6 +1877,8 @@ static void wpas_start_wps_go(struct wpa_supplicant *wpa_s,
        ssid->frequency = params->freq;
        ssid->ht40 = params->ht40;
        ssid->vht = params->vht;
+       ssid->max_oper_chwidth = params->max_oper_chwidth;
+       ssid->vht_center_freq2 = params->vht_center_freq2;
        ssid->ssid = os_zalloc(params->ssid_len + 1);
        if (ssid->ssid) {
                os_memcpy(ssid->ssid, params->ssid, params->ssid_len);
@@ -2178,6 +2180,8 @@ static void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
                res->ht40 = 1;
        if (wpa_s->p2p_go_vht)
                res->vht = 1;
+       res->max_oper_chwidth = wpa_s->p2p_go_max_oper_chwidth;
+       res->vht_center_freq2 = wpa_s->p2p_go_vht_center_freq2;
 
        wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_SUCCESS "role=%s "
                       "freq=%d ht40=%d peer_dev=" MACSTR " peer_iface=" MACSTR
@@ -2966,7 +2970,7 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
                if (s) {
                        int go = s->mode == WPAS_MODE_P2P_GO;
                        wpas_p2p_group_add_persistent(
-                               wpa_s, s, go, 0, op_freq, 0, 0, NULL,
+                               wpa_s, s, go, 0, op_freq, 0, 0, 0, 0, NULL,
                                go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0,
                                1);
                } else if (bssid) {
@@ -3183,7 +3187,9 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid,
                                      ssid->mode == WPAS_MODE_P2P_GO,
                                      wpa_s->p2p_persistent_go_freq,
                                      freq,
+                                     wpa_s->p2p_go_vht_center_freq2,
                                      wpa_s->p2p_go_ht40, wpa_s->p2p_go_vht,
+                                     wpa_s->p2p_go_max_oper_chwidth,
                                      channels,
                                      ssid->mode == WPAS_MODE_P2P_GO ?
                                      P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
@@ -4124,13 +4130,13 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
                        if (response_done && persistent_go) {
                                wpas_p2p_group_add_persistent(
                                        wpa_s, persistent_go,
-                                       0, 0, freq, 0, 0, NULL,
+                                       0, 0, freq, 0, 0, 0, 0, NULL,
                                        persistent_go->mode ==
                                        WPAS_MODE_P2P_GO ?
                                        P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE :
                                        0, 0);
                        } else if (response_done) {
-                               wpas_p2p_group_add(wpa_s, 1, freq, 0, 0);
+                               wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0);
                        }
 
                        if (passwd_id == DEV_PW_P2PS_DEFAULT) {
@@ -4234,11 +4240,11 @@ static int wpas_prov_disc_resp_cb(void *ctx)
 
        if (persistent_go) {
                wpas_p2p_group_add_persistent(
-                       wpa_s, persistent_go, 0, 0, 0, 0, 0, NULL,
+                       wpa_s, persistent_go, 0, 0, 0, 0, 0, 0, 0, NULL,
                        persistent_go->mode == WPAS_MODE_P2P_GO ?
                        P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0);
        } else {
-               wpas_p2p_group_add(wpa_s, 1, freq, 0, 0);
+               wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0);
        }
 
        return 1;
@@ -4756,10 +4762,12 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
                                         wpa_s->p2p_persistent_group, 0, 0, 0,
                                         wpa_s->p2p_go_intent,
                                         wpa_s->p2p_connect_freq,
+                                        wpa_s->p2p_go_vht_center_freq2,
                                         wpa_s->p2p_persistent_id,
                                         wpa_s->p2p_pd_before_go_neg,
                                         wpa_s->p2p_go_ht40,
-                                        wpa_s->p2p_go_vht);
+                                        wpa_s->p2p_go_vht,
+                                        wpa_s->p2p_go_max_oper_chwidth);
                        return;
                }
 
@@ -5264,12 +5272,15 @@ exit_free:
  *     initiating Group Owner negotiation
  * @go_intent: GO Intent or -1 to use default
  * @freq: Frequency for the group or 0 for auto-selection
+ * @freq2: Center frequency of segment 1 for the GO operating in VHT 80P80 mode
  * @persistent_id: Persistent group credentials to use for forcing GO
  *     parameters or -1 to generate new values (SSID/passphrase)
  * @pd: Whether to send Provision Discovery prior to GO Negotiation as an
  *     interoperability workaround when initiating group formation
  * @ht40: Start GO with 40 MHz channel width
  * @vht:  Start GO with VHT support
+ * @vht_chwidth: Channel width supported by GO operating with VHT support
+ *     (VHT_CHANWIDTH_*).
  * Returns: 0 or new PIN (if pin was %NULL) on success, -1 on unspecified
  *     failure, -2 on failure due to channel not currently available,
  *     -3 if forced channel is not supported
@@ -5277,8 +5288,9 @@ exit_free:
 int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                     const char *pin, enum p2p_wps_method wps_method,
                     int persistent_group, int auto_join, int join, int auth,
-                    int go_intent, int freq, int persistent_id, int pd,
-                    int ht40, int vht)
+                    int go_intent, int freq, unsigned int vht_center_freq2,
+                    int persistent_id, int pd, int ht40, int vht,
+                    unsigned int vht_chwidth)
 {
        int force_freq = 0, pref_freq = 0;
        int ret = 0, res;
@@ -5320,6 +5332,8 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
        wpa_s->p2p_pd_before_go_neg = !!pd;
        wpa_s->p2p_go_ht40 = !!ht40;
        wpa_s->p2p_go_vht = !!vht;
+       wpa_s->p2p_go_vht_center_freq2 = vht_center_freq2;
+       wpa_s->p2p_go_max_oper_chwidth = vht_chwidth;
 
        if (pin)
                os_strlcpy(wpa_s->p2p_pin, pin, sizeof(wpa_s->p2p_pin));
@@ -5718,7 +5732,8 @@ out:
 
 static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
                                   struct p2p_go_neg_results *params,
-                                  int freq, int ht40, int vht,
+                                  int freq, int vht_center_freq2, int ht40,
+                                  int vht, int max_oper_chwidth,
                                   const struct p2p_channels *channels)
 {
        struct wpa_used_freq_data *freqs;
@@ -5730,6 +5745,8 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
        params->role_go = 1;
        params->ht40 = ht40;
        params->vht = vht;
+       params->max_oper_chwidth = max_oper_chwidth;
+       params->vht_center_freq2 = vht_center_freq2;
 
        freqs = os_calloc(wpa_s->num_multichan_concurrent,
                          sizeof(struct wpa_used_freq_data));
@@ -5964,15 +5981,18 @@ wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
  * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface()
  * @persistent_group: Whether to create a persistent group
  * @freq: Frequency for the group or 0 to indicate no hardcoding
+ * @vht_center_freq2: segment_1 center frequency for GO operating in VHT 80P80
  * @ht40: Start GO with 40 MHz channel width
  * @vht:  Start GO with VHT support
+ * @vht_chwidth: channel bandwidth for GO operating with VHT support
  * Returns: 0 on success, -1 on failure
  *
  * This function creates a new P2P group with the local end as the Group Owner,
  * i.e., without using Group Owner Negotiation.
  */
 int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
-                      int freq, int ht40, int vht)
+                      int freq, int vht_center_freq2, int ht40, int vht,
+                      int max_oper_chwidth)
 {
        struct p2p_go_neg_results params;
 
@@ -5990,7 +6010,8 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
        if (freq < 0)
                return -1;
 
-       if (wpas_p2p_init_go_params(wpa_s, &params, freq, ht40, vht, NULL))
+       if (wpas_p2p_init_go_params(wpa_s, &params, freq, vht_center_freq2,
+                                   ht40, vht, max_oper_chwidth, NULL))
                return -1;
        if (params.freq &&
            !p2p_supported_freq_go(wpa_s->global->p2p, params.freq)) {
@@ -6080,8 +6101,10 @@ static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
 
 int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
                                  struct wpa_ssid *ssid, int addr_allocated,
-                                 int force_freq, int neg_freq, int ht40,
-                                 int vht, const struct p2p_channels *channels,
+                                 int force_freq, int neg_freq,
+                                 int vht_center_freq2, int ht40,
+                                 int vht, int max_oper_chwidth,
+                                 const struct p2p_channels *channels,
                                  int connection_timeout, int force_scan)
 {
        struct p2p_go_neg_results params;
@@ -6155,7 +6178,8 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
                return -1;
        }
 
-       if (wpas_p2p_init_go_params(wpa_s, &params, freq, ht40, vht, channels))
+       if (wpas_p2p_init_go_params(wpa_s, &params, freq, vht_center_freq2,
+                                   ht40, vht, max_oper_chwidth, channels))
                return -1;
 
        params.role_go = 1;
@@ -6682,7 +6706,8 @@ int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr)
 /* Invite to reinvoke a persistent group */
 int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                    struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
-                   int ht40, int vht, int pref_freq)
+                   int vht_center_freq2, int ht40, int vht, int max_chwidth,
+                   int pref_freq)
 {
        enum p2p_invite_role role;
        u8 *bssid = NULL;
@@ -6699,6 +6724,9 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
 
        wpa_s->p2p_persistent_go_freq = freq;
        wpa_s->p2p_go_ht40 = !!ht40;
+       wpa_s->p2p_go_vht = !!vht;
+       wpa_s->p2p_go_max_oper_chwidth = max_chwidth;
+       wpa_s->p2p_go_vht_center_freq2 = vht_center_freq2;
        if (ssid->mode == WPAS_MODE_P2P_GO) {
                role = P2P_INVITE_ROLE_GO;
                if (peer_addr == NULL) {
@@ -6771,6 +6799,8 @@ int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
        wpa_s->p2p_persistent_go_freq = 0;
        wpa_s->p2p_go_ht40 = 0;
        wpa_s->p2p_go_vht = 0;
+       wpa_s->p2p_go_vht_center_freq2 = 0;
+       wpa_s->p2p_go_max_oper_chwidth = 0;
 
        for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
                if (os_strcmp(wpa_s->ifname, ifname) == 0)
@@ -7701,10 +7731,12 @@ static int wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s,
        wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr, wpa_s->p2p_pin,
                         wpa_s->p2p_wps_method, wpa_s->p2p_persistent_group, 0,
                         0, 0, wpa_s->p2p_go_intent, wpa_s->p2p_connect_freq,
+                        wpa_s->p2p_go_vht_center_freq2,
                         wpa_s->p2p_persistent_id,
                         wpa_s->p2p_pd_before_go_neg,
                         wpa_s->p2p_go_ht40,
-                        wpa_s->p2p_go_vht);
+                        wpa_s->p2p_go_vht,
+                        wpa_s->p2p_go_max_oper_chwidth);
        return ret;
 }
 
@@ -8238,7 +8270,8 @@ static int wpas_p2p_nfc_join_group(struct wpa_supplicant *wpa_s,
 
        return wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
                                WPS_NFC, 0, 0, 1, 0, wpa_s->conf->p2p_go_intent,
-                               params->go_freq, -1, 0, 1, 1);
+                               params->go_freq, wpa_s->p2p_go_vht_center_freq2,
+                               -1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth);
 }
 
 
@@ -8314,7 +8347,8 @@ static int wpas_p2p_nfc_init_go_neg(struct wpa_supplicant *wpa_s,
                   "connection handover");
        return wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
                                WPS_NFC, 0, 0, 0, 0, wpa_s->conf->p2p_go_intent,
-                               forced_freq, -1, 0, 1, 1);
+                               forced_freq, wpa_s->p2p_go_vht_center_freq2,
+                               -1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth);
 }
 
 
@@ -8328,7 +8362,8 @@ static int wpas_p2p_nfc_resp_go_neg(struct wpa_supplicant *wpa_s,
                   "connection handover");
        res = wpas_p2p_connect(wpa_s, params->peer->p2p_device_addr, NULL,
                               WPS_NFC, 0, 0, 0, 1, wpa_s->conf->p2p_go_intent,
-                              forced_freq, -1, 0, 1, 1);
+                              forced_freq, wpa_s->p2p_go_vht_center_freq2,
+                              -1, 0, 1, 1, wpa_s->p2p_go_max_oper_chwidth);
        if (res)
                return res;
 
@@ -8711,7 +8746,7 @@ static int wpas_p2p_move_go_csa(struct wpa_supplicant *wpa_s)
         * TODO: This function may not always work correctly. For example,
         * when we have a running GO and a BSS on a DFS channel.
         */
-       if (wpas_p2p_init_go_params(wpa_s, &params, 0, 0, 0, NULL)) {
+       if (wpas_p2p_init_go_params(wpa_s, &params, 0, 0, 0, 0, 0, NULL)) {
                wpa_dbg(wpa_s, MSG_DEBUG,
                        "P2P CSA: Failed to select new frequency for GO");
                return -1;
@@ -8823,7 +8858,7 @@ static void wpas_p2p_move_go_no_csa(struct wpa_supplicant *wpa_s)
        wpa_supplicant_ap_deinit(wpa_s);
 
        /* Reselect the GO frequency */
-       if (wpas_p2p_init_go_params(wpa_s, &params, 0, 0, 0, NULL)) {
+       if (wpas_p2p_init_go_params(wpa_s, &params, 0, 0, 0, 0, 0, NULL)) {
                wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Failed to reselect freq");
                wpas_p2p_group_delete(wpa_s,
                                      P2P_GROUP_REMOVAL_GO_LEAVE_CHANNEL);
index 259d604..21ee41f 100644 (file)
@@ -35,16 +35,20 @@ struct wpa_supplicant * wpas_get_p2p_client_iface(struct wpa_supplicant *wpa_s,
 int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                     const char *pin, enum p2p_wps_method wps_method,
                     int persistent_group, int auto_join, int join,
-                    int auth, int go_intent, int freq, int persistent_id,
-                    int pd, int ht40, int vht);
+                    int auth, int go_intent, int freq,
+                    unsigned int vht_center_freq2, int persistent_id,
+                    int pd, int ht40, int vht, unsigned int max_oper_chwidth);
 int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s,
                                           int freq, struct wpa_ssid *ssid);
 int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
-                      int freq, int ht40, int vht);
+                      int freq, int vht_center_freq2, int ht40, int vht,
+                      int max_oper_chwidth);
 int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
                                  struct wpa_ssid *ssid, int addr_allocated,
-                                 int force_freq, int neg_freq, int ht40,
-                                 int vht, const struct p2p_channels *channels,
+                                 int force_freq, int neg_freq,
+                                 int vht_center_freq2, int ht40,
+                                 int vht, int max_oper_chwidth,
+                                 const struct p2p_channels *channels,
                                  int connection_timeout, int force_scan);
 struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
                                       struct wpa_ssid *ssid);
@@ -111,7 +115,8 @@ void wpas_sd_response(void *ctx, const u8 *sa, u16 update_indic,
 int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr);
 int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                    struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
-                   int ht40, int vht, int pref_freq);
+                   int vht_center_freq2, int ht40, int vht,
+                   int max_oper_chwidth, int pref_freq);
 int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
                          const u8 *peer_addr, const u8 *go_dev_addr);
 int wpas_p2p_presence_req(struct wpa_supplicant *wpa_s, u32 duration1,
index 56382ae..c66539d 100644 (file)
@@ -857,6 +857,9 @@ struct wpa_supplicant {
        int *p2p_group_common_freqs;
        unsigned int p2p_group_common_freqs_num;
        u8 p2ps_join_addr[ETH_ALEN];
+
+       unsigned int p2p_go_max_oper_chwidth;
+       unsigned int p2p_go_vht_center_freq2;
 #endif /* CONFIG_P2P */
 
        struct wpa_ssid *bgscan_ssid;