P2P: Inform driver of the operating channel following group formation
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>
This commit is contained in:
parent
079a28f7b8
commit
7c813acf9c
6 changed files with 76 additions and 0 deletions
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue