]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Inform driver of the operating channel following group formation
authorAhmad Kholaif <akholaif@qca.qualcomm.com>
Fri, 24 Jul 2015 00:07:55 +0000 (17:07 -0700)
committerJouni Malinen <j@w1.fi>
Wed, 29 Jul 2015 16:10:16 +0000 (19:10 +0300)
Upon GO Negotiation completion, if the remote peer becomes GO, send a
hint event over QCA vendor specific interface to inform the driver of
the likely operating channel of the P2P GO.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/drivers/driver.h
src/drivers/driver_nl80211.c
src/drivers/driver_nl80211.h
src/drivers/driver_nl80211_capa.c
wpa_supplicant/driver_i.h
wpa_supplicant/p2p_supplicant.c

index d5946f46f477851cfe89b9eedc5b626fdd10eefb..d73e6fdcda0102c712c12ecdd2e4d209e6792395 100644 (file)
@@ -3403,6 +3403,18 @@ struct wpa_driver_ops {
         * Returns 0 on success, -1 on failure
         */
        int (*set_band)(void *priv, enum set_band band);
+
+       /**
+        * set_prob_oper_freq - Indicate probable P2P operating channel
+        * @priv: Private driver interface data
+        * @freq: Channel frequency in MHz
+        * Returns 0 on success, -1 on failure
+        *
+        * This command can be used to inform the driver of the operating
+        * frequency that an ongoing P2P group formation is likely to come up
+        * on. Local device is assuming P2P Client role.
+        */
+       int (*set_prob_oper_freq)(void *priv, unsigned int freq);
 };
 
 
index 1f274065a701d272e28337a4b966477233fce4ff..fd598901b020213c2ccfba58b7800951d55b4171 100644 (file)
@@ -8509,6 +8509,52 @@ static int nl80211_set_band(void *priv, enum set_band band)
 }
 
 
+static int nl80211_set_prob_oper_freq(void *priv, unsigned int freq)
+{
+       struct i802_bss *bss = priv;
+       struct wpa_driver_nl80211_data *drv = bss->drv;
+       struct nl_msg *msg;
+       int ret;
+       struct nlattr *params;
+
+       if (!drv->set_prob_oper_freq)
+               return -1;
+
+       wpa_printf(MSG_DEBUG,
+                  "nl80211: Set P2P probable operating freq %u for ifindex %d",
+                  freq, bss->ifindex);
+
+       if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
+           nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
+           nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+                       QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL) ||
+           !(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
+           nla_put_u32(msg,
+                       QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_IFACE_TYPE,
+                       QCA_IFACE_TYPE_P2P_CLIENT) ||
+           nla_put_u32(msg,
+                       QCA_WLAN_VENDOR_ATTR_PROBABLE_OPER_CHANNEL_FREQ,
+                       freq)) {
+               wpa_printf(MSG_ERROR,
+                          "%s: err in adding vendor_cmd and vendor_data",
+                          __func__);
+               nlmsg_free(msg);
+               return -1;
+       }
+       nla_nest_end(msg, params);
+
+       ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+       msg = NULL;
+       if (ret) {
+               wpa_printf(MSG_ERROR, "%s: err in send_and_recv_msgs",
+                          __func__);
+               return ret;
+       }
+       nlmsg_free(msg);
+       return 0;
+}
+
+
 const struct wpa_driver_ops wpa_driver_nl80211_ops = {
        .name = "nl80211",
        .desc = "Linux nl80211/cfg80211",
@@ -8617,4 +8663,5 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
        .del_tx_ts = nl80211_del_ts,
        .do_acs = wpa_driver_do_acs,
        .set_band = nl80211_set_band,
+       .set_prob_oper_freq = nl80211_set_prob_oper_freq,
 };
index 1536d2ffbd2a2ea3461f374170ebf353a6ea9845..078df4c0ffdea26581adbdeca94be6323a285616 100644 (file)
@@ -146,6 +146,7 @@ struct wpa_driver_nl80211_data {
        unsigned int set_rekey_offload:1;
        unsigned int p2p_go_ctwindow_supported:1;
        unsigned int setband_vendor_cmd_avail:1;
+       unsigned int set_prob_oper_freq:1;
 
        u64 remain_on_chan_cookie;
        u64 send_action_cookie;
index 926c1154572db6fa084559b9f3dc9ed6387c308f..e56f111382757757d4ea5e66281083b8017a1747 100644 (file)
@@ -589,6 +589,9 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
                                case QCA_NL80211_VENDOR_SUBCMD_GET_FEATURES:
                                        drv->get_features_vendor_cmd_avail = 1;
                                        break;
+                               case QCA_NL80211_VENDOR_SUBCMD_SET_PROBABLE_OPER_CHANNEL:
+                                       drv->set_prob_oper_freq = 1;
+                                       break;
                                case QCA_NL80211_VENDOR_SUBCMD_DO_ACS:
                                        drv->capa.flags |=
                                                WPA_DRIVER_FLAGS_ACS_OFFLOAD;
index d1f9f8be1be432ce01e5e67b3010e9bd136c9fe0..6ce4c2727191b4c54e5aee6b176df54d723dc8e5 100644 (file)
@@ -893,4 +893,12 @@ static inline int wpa_drv_setband(struct wpa_supplicant *wpa_s,
        return wpa_s->driver->set_band(wpa_s->drv_priv, band);
 }
 
+static inline int wpa_drv_set_prob_oper_freq(struct wpa_supplicant *wpa_s,
+                                            unsigned int freq)
+{
+       if (!wpa_s->driver->set_prob_oper_freq)
+               return 0;
+       return wpa_s->driver->set_prob_oper_freq(wpa_s->drv_priv, freq);
+}
+
 #endif /* DRIVER_I_H */
index 541cb206429c2cdae13705da9a435e727451dba7..8f90e38ad6648994143a3db7745ecffa3ef67627 100644 (file)
@@ -2081,6 +2081,11 @@ static void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
                return;
        }
 
+       if (!res->role_go) {
+               /* Inform driver of the operating channel of GO. */
+               wpa_drv_set_prob_oper_freq(wpa_s, res->freq);
+       }
+
        if (wpa_s->p2p_go_ht40)
                res->ht40 = 1;
        if (wpa_s->p2p_go_vht)