752 lines
25 KiB
Diff
752 lines
25 KiB
Diff
From 013beb7bc5036bf627fce3707a7a83344ffa05aa Mon Sep 17 00:00:00 2001
|
|
From: Gokul Sivakumar <gokulkumar.sivakumar@infineon.com>
|
|
Date: Mon, 11 Jul 2022 11:16:37 +0530
|
|
Subject: [PATCH 41/60] add support to offload TWT setup request handling to
|
|
the Firmware
|
|
|
|
With "TWT_SETUP" control sock cmd interface currently available in the
|
|
wpa_supplicant, it is currently possible to generate the TWT Setup Action
|
|
frame with the desired TWT session params like SP, SI, TWT Setup cmd type,
|
|
Flow ID, Trigger/Non-Trigger based, Un-Announced/Announced session types,
|
|
etc, without informing the TWT state machine in the Firmware.
|
|
|
|
Now introduce a new TWT Offload code path and then when the TWT Setup is
|
|
triggerd either through the "$ wpa_cli twt_setup" or directly though the
|
|
control sock cmd "TWT_SETUP", construct a Vendor nl80211 cmd of type "TWT"
|
|
and pass it to the driver if it supports this new vendor cmd. The driver
|
|
then could inform the TWT module in the firmware through the corresponding
|
|
IOVAR to initiate a TWT Setup request while updating the TWT negotiation
|
|
handshake state machine as needed.
|
|
|
|
Upstream-Status: Inappropriate [DEY specific]
|
|
|
|
Signed-off-by: Gokul Sivakumar <gokulkumar.sivakumar@infineon.com>
|
|
Signed-off-by: Ian Lin <ian.lin@infineon.com>
|
|
---
|
|
src/common/ifx_vendor.h | 157 ++++++++++++++++++++++++++++++
|
|
src/drivers/driver.h | 38 ++++++++
|
|
src/drivers/driver_nl80211.c | 124 ++++++++++++++++++++++-
|
|
src/drivers/driver_nl80211.h | 3 +
|
|
src/drivers/driver_nl80211_capa.c | 12 +++
|
|
wpa_supplicant/Makefile | 8 ++
|
|
wpa_supplicant/ctrl_iface.c | 12 ++-
|
|
wpa_supplicant/defconfig_base | 7 ++
|
|
wpa_supplicant/driver_i.h | 12 +++
|
|
wpa_supplicant/twt.c | 119 +++++++++++++++++++++-
|
|
wpa_supplicant/wpa_supplicant_i.h | 8 ++
|
|
11 files changed, 494 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/src/common/ifx_vendor.h b/src/common/ifx_vendor.h
|
|
index 2ea9af0a7..a94694c93 100644
|
|
--- a/src/common/ifx_vendor.h
|
|
+++ b/src/common/ifx_vendor.h
|
|
@@ -54,6 +54,9 @@
|
|
*
|
|
* @IFX_VENDOR_SCMD_AMSDU: Vendor command to enable/disable AMSDU on all the TID queues
|
|
*
|
|
+ * @IFX_VENDOR_SCMD_TWT: Vendor subcommand to configure TWT
|
|
+ * Uses attributes defined in enum ifx_vendor_attr_twt.
|
|
+ *
|
|
* @IFX_VENDOR_SCMD_MAX: This acts as a the tail of cmds list.
|
|
* Make sure it located at the end of the list.
|
|
*/
|
|
@@ -70,6 +73,7 @@ enum ifx_nl80211_vendor_subcmds {
|
|
IFX_VENDOR_SCMD_MUEDCA_OPT_ENABLE = 11,
|
|
IFX_VENDOR_SCMD_LDPC_CAP = 12,
|
|
IFX_VENDOR_SCMD_AMSDU = 13,
|
|
+ IFX_VENDOR_SCMD_TWT = 14,
|
|
IFX_VENDOR_SCMD_MAX
|
|
};
|
|
|
|
@@ -92,4 +96,157 @@ enum ifx_vendor_attr {
|
|
IFX_VENDOR_ATTR_MAX = 11
|
|
};
|
|
|
|
+/*
|
|
+ * enum ifx_vendor_attr_twt - Attributes for the TWT vendor command
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_UNSPEC: Reserved value 0
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_OPER: To specify the type of TWT operation
|
|
+ * to be performed. Uses attributes defined in enum ifx_twt_oper.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAMS: Nester attributes representing the
|
|
+ * parameters configured for TWT. These parameters are defined in
|
|
+ * the enum ifx_vendor_attr_twt_param.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_MAX: This acts as a the tail of cmds list.
|
|
+ * Make sure it located at the end of the list.
|
|
+ */
|
|
+enum ifx_vendor_attr_twt {
|
|
+ IFX_VENDOR_ATTR_TWT_UNSPEC,
|
|
+ IFX_VENDOR_ATTR_TWT_OPER,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAMS,
|
|
+ IFX_VENDOR_ATTR_TWT_MAX
|
|
+};
|
|
+
|
|
+/*
|
|
+ * enum ifx_twt_oper - TWT operation to be specified using the vendor
|
|
+ * attribute IFX_VENDOR_ATTR_TWT_OPER
|
|
+ *
|
|
+ * @IFX_TWT_OPER_UNSPEC: Reserved value 0
|
|
+ *
|
|
+ * @IFX_TWT_OPER_SETUP: Setup a TWT session. Required parameters are
|
|
+ * obtained through the nested attrs under IFX_VENDOR_ATTR_TWT_PARAMS.
|
|
+ *
|
|
+ * @IFX_TWT_OPER_MAX: This acts as a the tail of the list.
|
|
+ * Make sure it located at the end of the list.
|
|
+ */
|
|
+enum ifx_twt_oper {
|
|
+ IFX_TWT_OPER_UNSPEC,
|
|
+ IFX_TWT_OPER_SETUP,
|
|
+ IFX_TWT_OPER_MAX
|
|
+};
|
|
+
|
|
+/*
|
|
+ * enum ifx_vendor_attr_twt_param - TWT parameters
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC: Reserved value 0
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE: Specifies the type of Negotiation to be
|
|
+ * done during Setup. The four possible types are
|
|
+ * 0 - Individual TWT Negotiation
|
|
+ * 1 - Wake TBTT Negotiation
|
|
+ * 2 - Broadcast TWT in Beacon
|
|
+ * 3 - Broadcast TWT Membership Negotiation
|
|
+ *
|
|
+ * The possible values are defined in the enum ifx_twt_param_nego_type
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE: Specifies the type of TWT Setup frame
|
|
+ * when sent by the TWT Requesting STA
|
|
+ * 0 - Request
|
|
+ * 1 - Suggest
|
|
+ * 2 - Demand
|
|
+ *
|
|
+ * when sent by the TWT Responding STA.
|
|
+ * 3 - Grouping
|
|
+ * 4 - Accept
|
|
+ * 5 - Alternate
|
|
+ * 6 - Dictate
|
|
+ * 7 - Reject
|
|
+ *
|
|
+ * The possible values are defined in the enum ifx_twt_oper_setup_cmd_type.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN: Dialog Token used by the TWT Requesting STA to
|
|
+ * identify the TWT Setup request/response transaction.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME: Target Wake Time.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION: Nominal Minimum TWT Wake Duration.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT: TWT Wake Interval Exponent.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA: TWT Wake Interval Mantissa.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR: Specify this is a TWT Requesting / Responding STA.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER: Specify Trigger based / Non-Trigger based TWT Session.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT: Specify Implicit / Explicit TWT session.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE: Specify Un-Announced / Announced TWT session.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID: Flow ID of an iTWT session.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID: Brocast TWT ID of a bTWT session.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION: Specifies whether Tx within SP is protected.
|
|
+ * Set to 1 to indicate that TXOPs within the TWT SPs shall be initiated
|
|
+ * with a NAV protection mechanism, such as (MU) RTS/CTS or CTS-to-self frame;
|
|
+ * otherwise, it shall set it to 0.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL: TWT channel field which is set to 0, unless
|
|
+ * the HE STA sets up a subchannel selective transmission operation.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED: TWT Information frame RX handing
|
|
+ * disabled / enabled.
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT: Nominal Minimum TWT Wake Duration
|
|
+ * Unit. 0 represents unit in "256 usecs" and 1 represents unit in "TUs".
|
|
+ *
|
|
+ * @IFX_VENDOR_ATTR_TWT_PARAM_MAX: This acts as a the tail of the list.
|
|
+ * Make sure it located at the end of the list.
|
|
+ */
|
|
+enum ifx_vendor_attr_twt_param {
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_UNSPEC,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT,
|
|
+ IFX_VENDOR_ATTR_TWT_PARAM_MAX
|
|
+};
|
|
+
|
|
+enum ifx_twt_param_nego_type {
|
|
+ IFX_TWT_PARAM_NEGO_TYPE_INVALID = -1,
|
|
+ IFX_TWT_PARAM_NEGO_TYPE_ITWT = 0,
|
|
+ IFX_TWT_PARAM_NEGO_TYPE_WAKE_TBTT = 1,
|
|
+ IFX_TWT_PARAM_NEGO_TYPE_BTWT_IE_BCN = 2,
|
|
+ IFX_TWT_PARAM_NEGO_TYPE_BTWT = 3,
|
|
+ IFX_TWT_PARAM_NEGO_TYPE_MAX = 4
|
|
+};
|
|
+
|
|
+enum ifx_twt_oper_setup_cmd_type {
|
|
+ IFX_TWT_OPER_SETUP_CMD_TYPE_INVALID = -1,
|
|
+ IFX_TWT_OPER_SETUP_CMD_TYPE_REQUEST = 0,
|
|
+ IFX_TWT_OPER_SETUP_CMD_TYPE_SUGGEST = 1,
|
|
+ IFX_TWT_OPER_SETUP_CMD_TYPE_DEMAND = 2,
|
|
+ IFX_TWT_OPER_SETUP_CMD_TYPE_GROUPING = 3,
|
|
+ IFX_TWT_OPER_SETUP_CMD_TYPE_ACCEPT = 4,
|
|
+ IFX_TWT_OPER_SETUP_CMD_TYPE_ALTERNATE = 5,
|
|
+ IFX_TWT_OPER_SETUP_CMD_TYPE_DICTATE = 6,
|
|
+ IFX_TWT_OPER_SETUP_CMD_TYPE_REJECT = 7,
|
|
+ IFX_TWT_OPER_SETUP_CMD_TYPE_MAX = 8
|
|
+};
|
|
+
|
|
#endif /* IFX_VENDOR_H */
|
|
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
|
|
index d778b1eaa..af4d0a5d0 100644
|
|
--- a/src/drivers/driver.h
|
|
+++ b/src/drivers/driver.h
|
|
@@ -26,6 +26,9 @@
|
|
#include "pae/ieee802_1x_kay.h"
|
|
#endif /* CONFIG_MACSEC */
|
|
#include "utils/list.h"
|
|
+#ifdef CONFIG_DRIVER_NL80211_IFX
|
|
+#include "common/ifx_vendor.h"
|
|
+#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
|
|
#define HOSTAPD_CHAN_DISABLED 0x00000001
|
|
#define HOSTAPD_CHAN_NO_IR 0x00000002
|
|
@@ -2519,6 +2522,31 @@ struct drv_acs_params {
|
|
int edmg_enabled;
|
|
};
|
|
|
|
+#ifdef CONFIG_DRIVER_NL80211_IFX
|
|
+#ifdef CONFIG_TWT_OFFLOAD_IFX
|
|
+struct drv_setup_twt_params {
|
|
+ u8 dtok;
|
|
+ u64 twt;
|
|
+ u8 min_twt;
|
|
+ u8 exponent;
|
|
+ u16 mantissa;
|
|
+ enum ifx_twt_oper_setup_cmd_type setup_cmd;
|
|
+ u8 requestor;
|
|
+ u8 trigger;
|
|
+ u8 implicit;
|
|
+ u8 flow_type;
|
|
+ u8 flow_id;
|
|
+ u8 bcast_twt_id;
|
|
+ u8 protection;
|
|
+ u8 twt_channel;
|
|
+ u8 control;
|
|
+ enum ifx_twt_param_nego_type negotiation_type;
|
|
+ u8 twt_info_frame_disabled;
|
|
+ u8 min_twt_unit; /* true - in TUs, false - in 256us */
|
|
+};
|
|
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
|
|
+#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
+
|
|
struct wpa_bss_trans_info {
|
|
u8 mbo_transition_reason;
|
|
u8 n_candidates;
|
|
@@ -4630,6 +4658,16 @@ struct wpa_driver_ops {
|
|
const u8 *match, size_t match_len,
|
|
bool multicast);
|
|
#endif /* CONFIG_TESTING_OPTIONS */
|
|
+
|
|
+#ifdef CONFIG_DRIVER_NL80211_IFX
|
|
+#ifdef CONFIG_TWT_OFFLOAD_IFX
|
|
+ /**
|
|
+ * setup_twt - Setup a TWT session
|
|
+ * @params: Setup TWT params
|
|
+ */
|
|
+ int (*setup_twt)(void *priv, struct drv_setup_twt_params *params);
|
|
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
|
|
+#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
};
|
|
|
|
/**
|
|
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
|
|
index de58b17e1..fd6fe91a1 100644
|
|
--- a/src/drivers/driver_nl80211.c
|
|
+++ b/src/drivers/driver_nl80211.c
|
|
@@ -43,7 +43,9 @@
|
|
#include "radiotap_iter.h"
|
|
#include "rfkill.h"
|
|
#include "driver_nl80211.h"
|
|
-
|
|
+#ifdef CONFIG_DRIVER_NL80211_IFX
|
|
+#include "common/ifx_vendor.h"
|
|
+#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
|
|
#ifndef NETLINK_CAP_ACK
|
|
#define NETLINK_CAP_ACK 10
|
|
@@ -12284,6 +12286,121 @@ static int testing_nl80211_register_frame(void *priv, u16 type,
|
|
}
|
|
#endif /* CONFIG_TESTING_OPTIONS */
|
|
|
|
+#ifdef CONFIG_DRIVER_NL80211_IFX
|
|
+#ifdef CONFIG_TWT_OFFLOAD_IFX
|
|
+static int wpa_driver_nl80211_setup_twt(void *priv, struct drv_setup_twt_params *params)
|
|
+{
|
|
+ struct i802_bss *bss = priv;
|
|
+ struct wpa_driver_nl80211_data *drv = bss->drv;
|
|
+ struct nl_msg *msg = NULL;
|
|
+ struct nlattr *data, *twt_param_attrs;
|
|
+ int ret = -1;
|
|
+
|
|
+ if (!drv->ifx_twt_offload)
|
|
+ goto fail;
|
|
+
|
|
+ if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
|
|
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_IFX) ||
|
|
+ nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, IFX_VENDOR_SCMD_TWT))
|
|
+ goto fail;
|
|
+
|
|
+ data = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
|
|
+ if (!data)
|
|
+ goto fail;
|
|
+
|
|
+ if (nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_OPER, IFX_TWT_OPER_SETUP))
|
|
+ goto fail;
|
|
+
|
|
+ twt_param_attrs = nla_nest_start(msg, IFX_VENDOR_ATTR_TWT_PARAMS);
|
|
+ if (!twt_param_attrs)
|
|
+ goto fail;
|
|
+
|
|
+ if (nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_NEGO_TYPE,
|
|
+ params->negotiation_type) ||
|
|
+
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_SETUP_CMD_TYPE,
|
|
+ params->setup_cmd) ||
|
|
+
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_DIALOG_TOKEN,
|
|
+ params->dtok) ||
|
|
+
|
|
+ (params->twt &&
|
|
+ nla_put_u64(msg, IFX_VENDOR_ATTR_TWT_PARAM_WAKE_TIME,
|
|
+ params->twt)) ||
|
|
+
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION,
|
|
+ params->min_twt) ||
|
|
+
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_EXPONENT,
|
|
+ params->exponent) ||
|
|
+
|
|
+ nla_put_u16(msg, IFX_VENDOR_ATTR_TWT_PARAM_WAKE_INTVL_MANTISSA,
|
|
+ params->mantissa) ||
|
|
+
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_REQUESTOR,
|
|
+ params->requestor) ||
|
|
+
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_TRIGGER,
|
|
+ params->trigger) ||
|
|
+
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_IMPLICIT,
|
|
+ params->implicit) ||
|
|
+
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_FLOW_TYPE,
|
|
+ params->flow_type) ||
|
|
+
|
|
+ (params->flow_id &&
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_FLOW_ID,
|
|
+ params->flow_id)) ||
|
|
+
|
|
+ (params->bcast_twt_id &&
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_BCAST_TWT_ID,
|
|
+ params->bcast_twt_id)) ||
|
|
+
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_PROTECTION,
|
|
+ params->protection) ||
|
|
+
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_CHANNEL,
|
|
+ params->twt_channel) ||
|
|
+
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_TWT_INFO_FRAME_DISABLED,
|
|
+ params->twt_info_frame_disabled) ||
|
|
+
|
|
+ nla_put_u8(msg, IFX_VENDOR_ATTR_TWT_PARAM_MIN_WAKE_DURATION_UNIT,
|
|
+ params->min_twt_unit))
|
|
+ goto fail;
|
|
+
|
|
+ nla_nest_end(msg, twt_param_attrs);
|
|
+ nla_nest_end(msg, data);
|
|
+
|
|
+ wpa_printf(MSG_DEBUG,
|
|
+ "nl80211: TWT Setup: Neg Type: %d REQ Type: %d TWT: %lu min_twt: %d "
|
|
+ "exponent: %d mantissa: %d requestor: %d trigger: %d implicit: %d "
|
|
+ "flow_type: %d flow_id: %d bcast_twt_id: %d protection: %d "
|
|
+ "twt_channel: %d twt_info_frame_disabled: %d min_twt_unit: %d",
|
|
+ params->negotiation_type, params->setup_cmd, params->twt,
|
|
+ params->min_twt, params->exponent, params->mantissa,
|
|
+ params->requestor, params->trigger, params->implicit,
|
|
+ params->flow_type, params->flow_id, params->bcast_twt_id,
|
|
+ params->protection, params->twt_channel,
|
|
+ params->twt_info_frame_disabled, params->min_twt_unit);
|
|
+
|
|
+ ret = send_and_recv_msgs(drv, msg, NULL, NULL, NULL, NULL);
|
|
+ if (ret < 0) {
|
|
+ wpa_printf(MSG_DEBUG,
|
|
+ "nl80211: TWT Setup: Failed to invoke driver "
|
|
+ "TWT setup function: %s",
|
|
+ strerror(-ret));
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+fail:
|
|
+ nl80211_nlmsg_clear(msg);
|
|
+ nlmsg_free(msg);
|
|
+ return ret;
|
|
+}
|
|
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
|
|
+#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
|
|
const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
|
.name = "nl80211",
|
|
@@ -12429,4 +12546,9 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
|
|
#ifdef CONFIG_TESTING_OPTIONS
|
|
.register_frame = testing_nl80211_register_frame,
|
|
#endif /* CONFIG_TESTING_OPTIONS */
|
|
+#ifdef CONFIG_DRIVER_NL80211_IFX
|
|
+#ifdef CONFIG_TWT_OFFLOAD_IFX
|
|
+ .setup_twt = wpa_driver_nl80211_setup_twt,
|
|
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
|
|
+#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
};
|
|
diff --git a/src/drivers/driver_nl80211.h b/src/drivers/driver_nl80211.h
|
|
index 80d456472..f681afb41 100644
|
|
--- a/src/drivers/driver_nl80211.h
|
|
+++ b/src/drivers/driver_nl80211.h
|
|
@@ -180,6 +180,9 @@ struct wpa_driver_nl80211_data {
|
|
unsigned int unsol_bcast_probe_resp:1;
|
|
unsigned int qca_do_acs:1;
|
|
unsigned int brcm_do_acs:1;
|
|
+#ifdef CONFIG_DRIVER_NL80211_IFX
|
|
+ unsigned int ifx_twt_offload:1;
|
|
+#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
|
|
u64 vendor_scan_cookie;
|
|
u64 remain_on_chan_cookie;
|
|
diff --git a/src/drivers/driver_nl80211_capa.c b/src/drivers/driver_nl80211_capa.c
|
|
index d5cdafa9f..19d1569bf 100644
|
|
--- a/src/drivers/driver_nl80211_capa.c
|
|
+++ b/src/drivers/driver_nl80211_capa.c
|
|
@@ -17,6 +17,9 @@
|
|
#include "common/qca-vendor.h"
|
|
#include "common/qca-vendor-attr.h"
|
|
#include "common/brcm_vendor.h"
|
|
+#ifdef CONFIG_DRIVER_NL80211_IFX
|
|
+#include "common/ifx_vendor.h"
|
|
+#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
#include "driver_nl80211.h"
|
|
|
|
|
|
@@ -1049,6 +1052,15 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg)
|
|
break;
|
|
}
|
|
#endif /* CONFIG_DRIVER_NL80211_BRCM */
|
|
+
|
|
+#ifdef CONFIG_DRIVER_NL80211_IFX
|
|
+ } else if (vinfo->vendor_id == OUI_IFX) {
|
|
+ switch (vinfo->subcmd) {
|
|
+ case IFX_VENDOR_SCMD_TWT:
|
|
+ drv->ifx_twt_offload = 1;
|
|
+ break;
|
|
+ }
|
|
+#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
}
|
|
|
|
wpa_printf(MSG_DEBUG, "nl80211: Supported vendor command: vendor_id=0x%x subcmd=%u",
|
|
diff --git a/wpa_supplicant/Makefile b/wpa_supplicant/Makefile
|
|
index 66aedaff7..16e484ce6 100644
|
|
--- a/wpa_supplicant/Makefile
|
|
+++ b/wpa_supplicant/Makefile
|
|
@@ -823,6 +823,14 @@ CFLAGS += -DCONFIG_WPS_STRICT
|
|
OBJS += ../src/wps/wps_validate.o
|
|
endif
|
|
|
|
+ifdef CONFIG_DRIVER_NL80211_IFX
|
|
+CFLAGS += -DCONFIG_DRIVER_NL80211_IFX
|
|
+endif # CONFIG_DRIVER_NL80211_IFX == y
|
|
+
|
|
+ifdef CONFIG_TWT_OFFLOAD_IFX
|
|
+CFLAGS += -DCONFIG_TWT_OFFLOAD_IFX
|
|
+endif # CONFIG_TWT_OFFLOAD_IFX == y
|
|
+
|
|
ifdef CONFIG_WPS_TESTING
|
|
CFLAGS += -DCONFIG_WPS_TESTING
|
|
endif
|
|
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
|
|
index 1d4c8bcc2..f93b8d65e 100644
|
|
--- a/wpa_supplicant/ctrl_iface.c
|
|
+++ b/wpa_supplicant/ctrl_iface.c
|
|
@@ -9988,6 +9988,7 @@ static int wpas_ctrl_resend_assoc(struct wpa_supplicant *wpa_s)
|
|
return -1;
|
|
#endif /* CONFIG_SME */
|
|
}
|
|
+#endif /* CONFIG_TESTING_OPTIONS */
|
|
|
|
|
|
static int wpas_ctrl_iface_send_twt_setup(struct wpa_supplicant *wpa_s,
|
|
@@ -10066,10 +10067,18 @@ static int wpas_ctrl_iface_send_twt_setup(struct wpa_supplicant *wpa_s,
|
|
if (tok_s)
|
|
control = atoi(tok_s + os_strlen(" control="));
|
|
|
|
+#ifdef CONFIG_TWT_OFFLOAD_IFX
|
|
+ return wpas_twt_offload_send_setup(wpa_s, dtok, exponent, mantissa,
|
|
+ min_twt, setup_cmd, twt, requestor,
|
|
+ trigger, implicit, flow_type,
|
|
+ flow_id, protection, twt_channel,
|
|
+ control);
|
|
+#else
|
|
return wpas_twt_send_setup(wpa_s, dtok, exponent, mantissa, min_twt,
|
|
setup_cmd, twt, requestor, trigger, implicit,
|
|
flow_type, flow_id, protection, twt_channel,
|
|
control);
|
|
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
|
|
}
|
|
|
|
|
|
@@ -10086,7 +10095,6 @@ static int wpas_ctrl_iface_send_twt_teardown(struct wpa_supplicant *wpa_s,
|
|
return wpas_twt_send_teardown(wpa_s, flags);
|
|
}
|
|
|
|
-#endif /* CONFIG_TESTING_OPTIONS */
|
|
|
|
|
|
static int wpas_ctrl_vendor_elem_add(struct wpa_supplicant *wpa_s, char *cmd)
|
|
@@ -12202,6 +12210,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
|
sme_event_unprot_disconnect(
|
|
wpa_s, wpa_s->bssid, NULL,
|
|
WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA);
|
|
+#endif /* CONFIG_TESTING_OPTIONS */
|
|
} else if (os_strncmp(buf, "TWT_SETUP ", 10) == 0) {
|
|
if (wpas_ctrl_iface_send_twt_setup(wpa_s, buf + 9))
|
|
reply_len = -1;
|
|
@@ -12214,7 +12223,6 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
|
} else if (os_strcmp(buf, "TWT_TEARDOWN") == 0) {
|
|
if (wpas_ctrl_iface_send_twt_teardown(wpa_s, ""))
|
|
reply_len = -1;
|
|
-#endif /* CONFIG_TESTING_OPTIONS */
|
|
} else if (os_strncmp(buf, "VENDOR_ELEM_ADD ", 16) == 0) {
|
|
if (wpas_ctrl_vendor_elem_add(wpa_s, buf + 16) < 0)
|
|
reply_len = -1;
|
|
diff --git a/wpa_supplicant/defconfig_base b/wpa_supplicant/defconfig_base
|
|
index 1c83967ae..bfaed5d91 100644
|
|
--- a/wpa_supplicant/defconfig_base
|
|
+++ b/wpa_supplicant/defconfig_base
|
|
@@ -641,3 +641,10 @@ CONFIG_TESTING_OPTIONS=y
|
|
|
|
CONFIG_SUITEB192=y
|
|
CONFIG_SUITEB=y
|
|
+
|
|
+# Enable all IFX/Cypress changes
|
|
+CONFIG_DRIVER_NL80211_IFX=y
|
|
+
|
|
+# Offload the TWT Session management to FW
|
|
+CONFIG_TWT_OFFLOAD_IFX=y
|
|
+
|
|
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
|
|
index c7ba94ebd..eab01da24 100644
|
|
--- a/wpa_supplicant/driver_i.h
|
|
+++ b/wpa_supplicant/driver_i.h
|
|
@@ -1127,4 +1127,16 @@ static inline int wpa_drv_dpp_listen(struct wpa_supplicant *wpa_s, bool enable)
|
|
return wpa_s->driver->dpp_listen(wpa_s->drv_priv, enable);
|
|
}
|
|
|
|
+#ifdef CONFIG_DRIVER_NL80211_IFX
|
|
+#ifdef CONFIG_TWT_OFFLOAD_IFX
|
|
+static inline int wpa_drv_setup_twt(struct wpa_supplicant *wpa_s,
|
|
+ struct drv_setup_twt_params *params)
|
|
+{
|
|
+ if (!wpa_s->driver->setup_twt)
|
|
+ return -1;
|
|
+ return wpa_s->driver->setup_twt(wpa_s->drv_priv, params);
|
|
+}
|
|
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
|
|
+#endif /* CONFIG_DRIVER_NL80211_IFX */
|
|
+
|
|
#endif /* DRIVER_I_H */
|
|
diff --git a/wpa_supplicant/twt.c b/wpa_supplicant/twt.c
|
|
index 8ec2c85ac..59933c875 100644
|
|
--- a/wpa_supplicant/twt.c
|
|
+++ b/wpa_supplicant/twt.c
|
|
@@ -12,8 +12,122 @@
|
|
#include "wpa_supplicant_i.h"
|
|
#include "driver_i.h"
|
|
|
|
+#ifdef CONFIG_TWT_OFFLOAD_IFX
|
|
+/**
|
|
+ * wpas_twt_offload_send_setup - Send TWT Setup frame to our AP
|
|
+ * @wpa_s: Pointer to wpa_supplicant
|
|
+ * @dtok: Dialog token
|
|
+ * @exponent: Wake-interval exponent
|
|
+ * @mantissa: Wake-interval mantissa
|
|
+ * @min_twt: Minimum TWT wake duration in units of 256 usec
|
|
+ * @setup_cmd: 0 == request, 1 == suggest, etc. Table 9-297
|
|
+ * @twt: Target Wake Time
|
|
+ * @requestor: Specify this is a TWT Requesting / Responding STA
|
|
+ * @trigger: Specify Trigger based / Non-Trigger based TWT Session
|
|
+ * @implicit: Specify Implicit / Explicit TWT session
|
|
+ * @flow_type: Specify Un-Announced / Announced TWT session
|
|
+ * @flow_id: Flow ID / Broacast TWT ID to be used in the TWT session
|
|
+ * @protection: Specifies whether Tx within SP is protected by RTS & CTS
|
|
+ * @twt_channel: Set by the HE SST non-AP STA
|
|
+ * @control: Control Field in the TWT Setup Action frame
|
|
+ * Returns: 0 in case of success, negative error code otherwise
|
|
+ *
|
|
+ */
|
|
+int wpas_twt_offload_send_setup(struct wpa_supplicant *wpa_s, u8 dtok, int exponent,
|
|
+ int mantissa, u8 min_twt, int setup_cmd, u64 twt,
|
|
+ bool requestor, bool trigger, bool implicit,
|
|
+ bool flow_type, u8 flow_id, bool protection,
|
|
+ u8 twt_channel, u8 control)
|
|
+{
|
|
+ int ret = 0;
|
|
+ struct drv_setup_twt_params params;
|
|
+ u8 negotiation_type, twt_info_frame_disabled, min_twt_unit;
|
|
+
|
|
+ params.dtok = dtok;
|
|
+ params.exponent = (u8)exponent;
|
|
+ params.mantissa = (u16)mantissa;
|
|
+ params.min_twt = min_twt;
|
|
+ params.twt = twt;
|
|
+ params.requestor = requestor ? 1 : 0;
|
|
+ params.trigger = trigger ? 1 : 0;
|
|
+ params.implicit = implicit ? 1 : 0;
|
|
+ params.flow_type = flow_type ? 1 : 0;
|
|
+ params.protection = protection ? 1 : 0;
|
|
+ params.twt_channel = twt_channel;
|
|
+ params.flow_id = 0;
|
|
+ params.bcast_twt_id = 0;
|
|
+
|
|
+ /* Setup Command Field - IEEE 802.11ax-2021 Table 9-297 */
|
|
+ switch(setup_cmd) {
|
|
+ case 0: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_REQUEST;
|
|
+ break;
|
|
+ case 1: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_SUGGEST;
|
|
+ break;
|
|
+ case 2: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_DEMAND;
|
|
+ break;
|
|
+ case 3: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_GROUPING;
|
|
+ break;
|
|
+ case 4: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_ACCEPT;
|
|
+ break;
|
|
+ case 5: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_ALTERNATE;
|
|
+ break;
|
|
+ case 6: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_DICTATE;
|
|
+ break;
|
|
+ case 7: params.setup_cmd = IFX_TWT_OPER_SETUP_CMD_TYPE_REJECT;
|
|
+ break;
|
|
+ default:
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "TWT offload: specified Setup cmd type not supported");
|
|
+ ret = -EOPNOTSUPP;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+ /* Control Field - IEEE 802.11ax-2021 Figure 9-687 */
|
|
+ params.control = control;
|
|
+ /* NDP Paging Indicator : Bit 0 */
|
|
+ /* Responder PM Mode : Bit 1 */
|
|
+ negotiation_type = (control & 0xc) >> 2; /* Negotiation type : Bit 2-3 */
|
|
+ twt_info_frame_disabled = (control & 0x10) >> 4;/* TWT Information Frame Disabled: Bit 4 */
|
|
+ min_twt_unit = (control & 0x20) >> 5; /* Wake Duration Unit : Bit 5 */
|
|
+ /* Reserved : Bit 6-7 */
|
|
+
|
|
+ /* Negotiation Type Field - IEEE 802.11ax-2021 Table 9.296a */
|
|
+ switch(negotiation_type) {
|
|
+ case 0: /* Individual TWT */
|
|
+ params.negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_ITWT;
|
|
+ params.flow_id = flow_id;
|
|
+ break;
|
|
+ case 1: /* Wake TBTT Negotiation */
|
|
+ params.negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_WAKE_TBTT;
|
|
+ break;
|
|
+ case 2: /* Broadcast TWT IE in Beacon */
|
|
+ params.negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_BTWT_IE_BCN;
|
|
+ break;
|
|
+ case 3: /* Broadcast TWT membership */
|
|
+ params.negotiation_type = IFX_TWT_PARAM_NEGO_TYPE_BTWT;
|
|
+ params.bcast_twt_id = flow_id;
|
|
+ break;
|
|
+ default:
|
|
+ wpa_printf(MSG_ERROR,
|
|
+ "TWT offload: specified Nego type not supported");
|
|
+ ret = -EOPNOTSUPP;
|
|
+ goto fail;
|
|
+ }
|
|
|
|
-#ifdef CONFIG_TESTING_OPTIONS
|
|
+ params.twt_info_frame_disabled = twt_info_frame_disabled;
|
|
+ params.min_twt_unit = min_twt_unit; /* 1 - in TUs, 0 - in 256us */
|
|
+
|
|
+ if (wpa_drv_setup_twt(wpa_s, ¶ms)) {
|
|
+ wpa_printf(MSG_ERROR, "TWT offload: Failed to send TWT Setup Request");
|
|
+ ret = -ECANCELED;
|
|
+ goto fail;
|
|
+ }
|
|
+
|
|
+fail:
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+#else
|
|
|
|
/**
|
|
* wpas_twt_send_setup - Send TWT Setup frame (Request) to our AP
|
|
@@ -95,6 +209,7 @@ int wpas_twt_send_setup(struct wpa_supplicant *wpa_s, u8 dtok, int exponent,
|
|
return ret;
|
|
}
|
|
|
|
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
|
|
|
|
/**
|
|
* wpas_twt_send_teardown - Send TWT teardown request to our AP
|
|
@@ -138,5 +253,3 @@ int wpas_twt_send_teardown(struct wpa_supplicant *wpa_s, u8 flags)
|
|
wpabuf_free(buf);
|
|
return ret;
|
|
}
|
|
-
|
|
-#endif /* CONFIG_TESTING_OPTIONS */
|
|
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
|
|
index b671b54e7..1f538724e 100644
|
|
--- a/wpa_supplicant/wpa_supplicant_i.h
|
|
+++ b/wpa_supplicant/wpa_supplicant_i.h
|
|
@@ -1643,11 +1643,19 @@ void add_freq(int *freqs, int *num_freqs, int freq);
|
|
int wpas_get_op_chan_phy(int freq, const u8 *ies, size_t ies_len,
|
|
u8 *op_class, u8 *chan, u8 *phy_type);
|
|
|
|
+#ifdef CONFIG_TWT_OFFLOAD_IFX
|
|
+int wpas_twt_offload_send_setup(struct wpa_supplicant *wpa_s, u8 dtok, int exponent,
|
|
+ int mantissa, u8 min_twt, int setup_cmd, u64 twt,
|
|
+ bool requestor, bool trigger, bool implicit,
|
|
+ bool flow_type, u8 flow_id, bool protection,
|
|
+ u8 twt_channel, u8 control);
|
|
+#else
|
|
int wpas_twt_send_setup(struct wpa_supplicant *wpa_s, u8 dtok, int exponent,
|
|
int mantissa, u8 min_twt, int setup_cmd, u64 twt,
|
|
bool requestor, bool trigger, bool implicit,
|
|
bool flow_type, u8 flow_id, bool protection,
|
|
u8 twt_channel, u8 control);
|
|
+#endif /* CONFIG_TWT_OFFLOAD_IFX */
|
|
int wpas_twt_send_teardown(struct wpa_supplicant *wpa_s, u8 flags);
|
|
|
|
void wpas_rrm_reset(struct wpa_supplicant *wpa_s);
|
|
--
|
|
2.17.1
|
|
|