aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunil Dutt <usdutt@qti.qualcomm.com>2016-10-25 15:41:04 (GMT)
committerJouni Malinen <j@w1.fi>2016-10-27 20:22:33 (GMT)
commit2e4e4fb71cce29181623f60d65bcb264059e24c7 (patch)
tree6ed239d1992bb4b75d6b2f8fec17a46f16764502
parent14cd203ffff4d2f831a8c58829b7d3fd068ed748 (diff)
downloadhostap-2e4e4fb71cce29181623f60d65bcb264059e24c7.zip
hostap-2e4e4fb71cce29181623f60d65bcb264059e24c7.tar.gz
hostap-2e4e4fb71cce29181623f60d65bcb264059e24c7.tar.bz2
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>
-rw-r--r--src/drivers/driver.h10
-rw-r--r--src/drivers/driver_nl80211.c51
-rw-r--r--wpa_supplicant/ctrl_iface.c2
-rw-r--r--wpa_supplicant/driver_i.h9
4 files changed, 72 insertions, 0 deletions
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 159a6b0..b6f2f82 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -3632,6 +3632,16 @@ struct wpa_driver_ops {
*/
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);
};
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 4dc1cec..75c4271 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -9325,6 +9325,56 @@ static int nl80211_p2p_lo_stop(void *priv)
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 */
@@ -9568,6 +9618,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.p2p_lo_start = nl80211_p2p_lo_start,
.p2p_lo_stop = nl80211_p2p_lo_stop,
.set_default_scan_ies = nl80211_set_default_scan_ies,
+ .set_tdls_mode = nl80211_set_tdls_mode,
#endif /* CONFIG_DRIVER_NL80211_QCA */
.configure_data_frame_filters = nl80211_configure_data_frame_filters,
.get_ext_capab = nl80211_get_ext_capab,
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index a929a7d..a754943 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -532,6 +532,8 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
#endif /* CONFIG_MBO */
} else if (os_strcasecmp(cmd, "lci") == 0) {
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 {
value[-1] = '=';
ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 5d5dcf0..f8efddc 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -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);
}
+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 */