nl80211: Allow TDLS trigger modes to be configured to the host driver
This commit adds a control interface command to configure the TDLS trigger mode to the host driver. This TDLS mode is configured through the "SET tdls_trigger_control" control interface command. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
14cd203fff
commit
2e4e4fb71c
4 changed files with 72 additions and 0 deletions
|
@ -3632,6 +3632,16 @@ struct wpa_driver_ops {
|
||||||
*/
|
*/
|
||||||
int (*set_default_scan_ies)(void *priv, const u8 *ies, size_t ies_len);
|
int (*set_default_scan_ies)(void *priv, const u8 *ies, size_t ies_len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set_tdls_mode - Set TDLS trigger mode to the host driver
|
||||||
|
* @priv: Private driver interface data
|
||||||
|
* @tdls_external_control: Represents if TDLS external trigger control
|
||||||
|
* mode is enabled/disabled.
|
||||||
|
*
|
||||||
|
* This optional callback can be used to configure the TDLS external
|
||||||
|
* trigger control mode to the host driver.
|
||||||
|
*/
|
||||||
|
int (*set_tdls_mode)(void *priv, int tdls_external_control);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9325,6 +9325,56 @@ static int nl80211_p2p_lo_stop(void *priv)
|
||||||
return send_and_recv_msgs(drv, msg, NULL, NULL);
|
return send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int nl80211_set_tdls_mode(void *priv, int tdls_external_control)
|
||||||
|
{
|
||||||
|
struct i802_bss *bss = priv;
|
||||||
|
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||||
|
struct nl_msg *msg;
|
||||||
|
struct nlattr *params;
|
||||||
|
int ret;
|
||||||
|
u32 tdls_mode;
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"nl80211: Set TDKS mode: tdls_external_control=%d",
|
||||||
|
tdls_external_control);
|
||||||
|
|
||||||
|
if (tdls_external_control == 1)
|
||||||
|
tdls_mode = QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT |
|
||||||
|
QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL;
|
||||||
|
else
|
||||||
|
tdls_mode = QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT;
|
||||||
|
|
||||||
|
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_CONFIGURE_TDLS))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
|
||||||
|
if (!params)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TRIGGER_MODE,
|
||||||
|
tdls_mode))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
nla_nest_end(msg, params);
|
||||||
|
|
||||||
|
ret = send_and_recv_msgs(drv, msg, NULL, NULL);
|
||||||
|
msg = NULL;
|
||||||
|
if (ret) {
|
||||||
|
wpa_printf(MSG_ERROR,
|
||||||
|
"nl80211: Set TDLS mode failed: ret=%d (%s)",
|
||||||
|
ret, strerror(-ret));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
nlmsg_free(msg);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||||
|
|
||||||
|
|
||||||
|
@ -9568,6 +9618,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
||||||
.p2p_lo_start = nl80211_p2p_lo_start,
|
.p2p_lo_start = nl80211_p2p_lo_start,
|
||||||
.p2p_lo_stop = nl80211_p2p_lo_stop,
|
.p2p_lo_stop = nl80211_p2p_lo_stop,
|
||||||
.set_default_scan_ies = nl80211_set_default_scan_ies,
|
.set_default_scan_ies = nl80211_set_default_scan_ies,
|
||||||
|
.set_tdls_mode = nl80211_set_tdls_mode,
|
||||||
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
#endif /* CONFIG_DRIVER_NL80211_QCA */
|
||||||
.configure_data_frame_filters = nl80211_configure_data_frame_filters,
|
.configure_data_frame_filters = nl80211_configure_data_frame_filters,
|
||||||
.get_ext_capab = nl80211_get_ext_capab,
|
.get_ext_capab = nl80211_get_ext_capab,
|
||||||
|
|
|
@ -532,6 +532,8 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
|
||||||
#endif /* CONFIG_MBO */
|
#endif /* CONFIG_MBO */
|
||||||
} else if (os_strcasecmp(cmd, "lci") == 0) {
|
} else if (os_strcasecmp(cmd, "lci") == 0) {
|
||||||
ret = wpas_ctrl_iface_set_lci(wpa_s, value);
|
ret = wpas_ctrl_iface_set_lci(wpa_s, value);
|
||||||
|
} else if (os_strcasecmp(cmd, "tdls_trigger_control") == 0) {
|
||||||
|
ret = wpa_drv_set_tdls_mode(wpa_s, atoi(value));
|
||||||
} else {
|
} else {
|
||||||
value[-1] = '=';
|
value[-1] = '=';
|
||||||
ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
|
ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
|
||||||
|
|
|
@ -968,4 +968,13 @@ static inline int wpa_drv_set_default_scan_ies(struct wpa_supplicant *wpa_s,
|
||||||
return wpa_s->driver->set_default_scan_ies(wpa_s->drv_priv, ies, len);
|
return wpa_s->driver->set_default_scan_ies(wpa_s->drv_priv, ies, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int wpa_drv_set_tdls_mode(struct wpa_supplicant *wpa_s,
|
||||||
|
int tdls_external_control)
|
||||||
|
{
|
||||||
|
if (!wpa_s->driver->set_tdls_mode)
|
||||||
|
return -1;
|
||||||
|
return wpa_s->driver->set_tdls_mode(wpa_s->drv_priv,
|
||||||
|
tdls_external_control);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* DRIVER_I_H */
|
#endif /* DRIVER_I_H */
|
||||||
|
|
Loading…
Reference in a new issue