qcacld-3.0: Make TWT commands as async

Add support for below TWT commands to be sent as asynchronous
commands from userspace:
1. TWT teardown
2. TWT pause
3. TWT resume

Change-Id: I1989fe153cc8a482a9616a7f6879de3b92ef82fb
CRs-Fixed: 2847143
This commit is contained in:
Pragaspathi Thilagaraj
2020-12-03 04:13:27 +05:30
committed by Gerrit - the friendly Code Review server
parent cfe2adce30
commit caf578f064
5 changed files with 283 additions and 422 deletions

View File

@@ -4025,10 +4025,15 @@ __wlan_hdd_cfg80211_get_features(struct wiphy *wiphy,
ucfg_mlme_get_twt_requestor(hdd_ctx->psoc, &twt_req);
ucfg_mlme_get_twt_responder(hdd_ctx->psoc, &twt_res);
if (twt_req || twt_res)
if (twt_req || twt_res) {
wlan_hdd_cfg80211_set_feature(feature_flags,
QCA_WLAN_VENDOR_FEATURE_TWT);
wlan_hdd_cfg80211_set_feature(
feature_flags,
QCA_WLAN_VENDOR_FEATURE_TWT_ASYNC_SUPPORT);
}
/* Check the kernel version for upstream commit aced43ce780dc5 that
* has support for processing user cell_base hints when wiphy is
* self managed or check the backport flag for the same.

View File

@@ -36,12 +36,8 @@
#include "cfg_ucfg_api.h"
#include <wlan_cp_stats_mc_ucfg_api.h>
#define TWT_SETUP_COMPLETE_TIMEOUT 4000
#define TWT_DISABLE_COMPLETE_TIMEOUT 4000
#define TWT_TERMINATE_COMPLETE_TIMEOUT 4000
#define TWT_PAUSE_COMPLETE_TIMEOUT 4000
#define TWT_NUDGE_COMPLETE_TIMEOUT 4000
#define TWT_RESUME_COMPLETE_TIMEOUT 4000
#define TWT_FLOW_TYPE_ANNOUNCED 0
#define TWT_FLOW_TYPE_UNANNOUNCED 1
@@ -52,17 +48,6 @@
#define TWT_WAKE_DURATION_MULTIPLICATION_FACTOR 256
#define TWT_MAX_NEXT_TWT_SIZE 3
/**
* struct twt_pause_dialog_comp_ev_priv - private struct for twt pause dialog
* @pause_dialog_comp_ev_buf: buffer from TWT pause dialog complete_event
*
* This TWT pause dialog private structure is registered with os_if to
* retrieve the TWT pause dialog response event buffer.
*/
struct twt_pause_dialog_comp_ev_priv {
struct wmi_twt_pause_dialog_complete_event_param pause_dialog_comp_ev_buf;
};
/**
* struct twt_nudge_dialog_comp_ev_priv - private struct for twt nudge dialog
* @nudge_dialog_comp_ev_buf: buffer from TWT nudge dialog complete_event
@@ -75,39 +60,6 @@ struct twt_nudge_dialog_comp_ev_priv {
nudge_dialog_comp_ev_buf;
};
/**
* struct twt_resume_dialog_comp_ev_priv - private struct for twt resume dialog
* @resume_dialog_comp_ev_buf: buffer from TWT resume dialog complete_event
*
* This TWT resume dialog private structure is registered with os_if to
* retrieve the TWT resume dialog response event buffer.
*/
struct twt_resume_dialog_comp_ev_priv {
struct wmi_twt_resume_dialog_complete_event_param res_dialog_comp_ev_buf;
};
/**
* struct twt_add_dialog_comp_ev_priv - private struct for twt add dialog
* @add_dialog_comp_ev_buf: buffer from TWT add dialog complete_event
*
* This TWT add dialog private structure is registered with os_if to
* retrieve the TWT add dialog response event buffer.
*/
struct twt_add_dialog_comp_ev_priv {
struct twt_add_dialog_complete_event add_dialog_comp_ev_buf;
};
/**
* struct twt_del_dialog_comp_ev_priv - private struct for twt del dialog
* @del_dialog_comp_ev_buf: buffer from TWT del dialog complete_event
*
* This TWT del dialog private structure is registered with os_if to
* retrieve the TWT del dialog response event buffer.
*/
struct twt_del_dialog_comp_ev_priv {
struct wmi_twt_del_dialog_complete_event_param del_dialog_comp_ev_buf;
};
static const struct nla_policy
qca_wlan_vendor_twt_add_dialog_policy[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_MAX + 1] = {
[QCA_WLAN_VENDOR_ATTR_TWT_SETUP_WAKE_INTVL_EXP] = {.type = NLA_U8 },
@@ -1127,27 +1079,34 @@ hdd_twt_setup_pack_resp_nlmsg(struct sk_buff *reply_skb,
/**
* hdd_send_twt_setup_response - Send TWT setup response to userspace
* @hdd_handle: Pointer to opaque HDD handle
* @hdd_adapter: Pointer to HDD adapter. This pointer is expeceted to
* be validated by the caller.
* @add_dialog_comp_ev_params: Add dialog completion event structure
*
* Return: QDF_STATUS
*/
static QDF_STATUS hdd_send_twt_setup_response(
hdd_handle_t hdd_handle,
struct hdd_adapter *adapter,
struct twt_add_dialog_complete_event *add_dialog_comp_ev_params)
{
struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
struct hdd_context *hdd_ctx;
struct sk_buff *twt_vendor_event;
struct wireless_dev *wdev = adapter->dev->ieee80211_ptr;
size_t data_len;
QDF_STATUS status;
bool additional_params_present = false;
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
status = wlan_hdd_validate_context(hdd_ctx);
if (QDF_IS_STATUS_ERROR(status))
return status;
if (add_dialog_comp_ev_params->params.num_additional_twt_params != 0)
additional_params_present = true;
data_len = hdd_get_twt_setup_event_len(additional_params_present);
twt_vendor_event = wlan_cfg80211_vendor_event_alloc(
hdd_ctx->wiphy, NULL, data_len,
hdd_ctx->wiphy, wdev, data_len,
QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT_INDEX,
GFP_KERNEL);
if (!twt_vendor_event) {
@@ -1171,25 +1130,29 @@ static QDF_STATUS hdd_send_twt_setup_response(
/**
* hdd_twt_add_dialog_comp_cb() - HDD callback for twt add dialog
* complete event
* @hdd_ctx: HDD Context
* @psoc: Pointer to global psoc
* @add_dialog_event: Pointer to Add dialog complete event structure
*
* Return: None
*/
static void
hdd_twt_add_dialog_comp_cb(hdd_handle_t hdd_handle,
hdd_twt_add_dialog_comp_cb(struct wlan_objmgr_psoc *psoc,
struct twt_add_dialog_complete_event *add_dialog_event)
{
hdd_enter();
struct hdd_adapter *adapter;
uint8_t vdev_id = add_dialog_event->params.vdev_id;
adapter = wlan_hdd_get_adapter_from_vdev(psoc, vdev_id);
if (!adapter) {
hdd_err("adapter is NULL");
return;
}
hdd_debug("TWT: add dialog_id:%d, status:%d vdev_id %d peer mac_addr "
QDF_MAC_ADDR_FMT, add_dialog_event->params.dialog_id,
add_dialog_event->params.status,
add_dialog_event->params.vdev_id,
add_dialog_event->params.status, vdev_id,
QDF_MAC_ADDR_REF(add_dialog_event->params.peer_macaddr));
hdd_send_twt_setup_response(hdd_handle, add_dialog_event);
hdd_exit();
hdd_send_twt_setup_response(adapter, add_dialog_event);
}
/**
@@ -1315,8 +1278,22 @@ static QDF_STATUS
hdd_twt_terminate_pack_resp_nlmsg(struct sk_buff *reply_skb,
struct wmi_twt_del_dialog_complete_event_param *params)
{
struct nlattr *config_attr;
int vendor_status;
if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
QCA_WLAN_TWT_TERMINATE)) {
hdd_err("TWT: Failed to put TWT operation");
return QDF_STATUS_E_FAILURE;
}
config_attr = nla_nest_start(reply_skb,
QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
if (!config_attr) {
hdd_err("TWT: nla_nest_start error");
return QDF_STATUS_E_INVAL;
}
if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID,
params->dialog_id)) {
hdd_debug("TWT: Failed to put dialog_id");
@@ -1330,44 +1307,72 @@ hdd_twt_terminate_pack_resp_nlmsg(struct sk_buff *reply_skb,
return QDF_STATUS_E_FAILURE;
}
nla_nest_end(reply_skb, config_attr);
return QDF_STATUS_SUCCESS;
}
/**
* hdd_twt_del_dialog_comp_cb() - callback function
* to get twt terminate command complete event
* @context: private context
* @psoc: Pointer to global psoc
* @params: Pointer to del dialog complete event buffer
*
* Return: None
*/
static void
hdd_twt_del_dialog_comp_cb(void *context,
hdd_twt_del_dialog_comp_cb(struct wlan_objmgr_psoc *psoc,
struct wmi_twt_del_dialog_complete_event_param *params)
{
struct osif_request *request;
struct twt_del_dialog_comp_ev_priv *priv;
struct hdd_adapter *adapter =
wlan_hdd_get_adapter_from_vdev(psoc, params->vdev_id);
struct wireless_dev *wdev;
struct hdd_context *hdd_ctx;
struct sk_buff *twt_vendor_event;
size_t data_len;
QDF_STATUS status;
hdd_enter();
request = osif_request_get(context);
if (!request) {
hdd_err("Obsolete request");
if (!adapter) {
hdd_err("adapter is NULL");
return;
}
priv = osif_request_priv(request);
qdf_mem_copy(&priv->del_dialog_comp_ev_buf, params,
sizeof(*params));
osif_request_complete(request);
osif_request_put(request);
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
status = wlan_hdd_validate_context(hdd_ctx);
if (QDF_IS_STATUS_ERROR(status))
return;
wdev = adapter->dev->ieee80211_ptr;
data_len = hdd_get_twt_event_len() + nla_total_size(sizeof(u8));
data_len += NLA_HDRLEN;
twt_vendor_event = wlan_cfg80211_vendor_event_alloc(
hdd_ctx->wiphy, wdev, data_len,
QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT_INDEX,
GFP_KERNEL);
if (!twt_vendor_event) {
hdd_err("TWT: Del dialog skb alloc failed");
return;
}
hdd_debug("TWT: del dialog_id:%d, status:%d vdev_id %d peer mac_addr "
QDF_MAC_ADDR_FMT, params->dialog_id,
params->status, params->vdev_id,
QDF_MAC_ADDR_REF(params->peer_macaddr));
status = hdd_twt_terminate_pack_resp_nlmsg(twt_vendor_event, params);
if (QDF_IS_STATUS_ERROR(status)) {
wlan_cfg80211_vendor_free_skb(twt_vendor_event);
return;
}
wlan_cfg80211_vendor_event(twt_vendor_event, GFP_KERNEL);
hdd_exit();
return;
}
/**
@@ -1381,73 +1386,17 @@ static
int hdd_send_twt_del_dialog_cmd(struct hdd_context *hdd_ctx,
struct wmi_twt_del_dialog_param *twt_params)
{
struct wmi_twt_del_dialog_complete_event_param *del_dialog_comp_ev_params;
struct twt_del_dialog_comp_ev_priv *priv;
static const struct osif_request_params osif_req_params = {
.priv_size = sizeof(*priv),
.timeout_ms = TWT_TERMINATE_COMPLETE_TIMEOUT,
.dealloc = NULL,
};
struct osif_request *request;
struct sk_buff *reply_skb = NULL;
QDF_STATUS status;
void *cookie;
int skb_len;
int ret = 0;
request = osif_request_alloc(&osif_req_params);
if (!request) {
hdd_err("twt osif request allocation failure");
ret = -ENOMEM;
goto err;
}
cookie = osif_request_cookie(request);
status = sme_del_dialog_cmd(hdd_ctx->mac_handle,
hdd_twt_del_dialog_comp_cb,
twt_params,
cookie);
if (!QDF_IS_STATUS_SUCCESS(status)) {
twt_params);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("Failed to send del dialog command");
ret = qdf_status_to_os_return(status);
goto err;
}
ret = osif_request_wait_for_response(request);
if (ret) {
hdd_err("twt: del dialog req timedout");
ret = -ETIMEDOUT;
goto err;
}
priv = osif_request_priv(request);
del_dialog_comp_ev_params = &priv->del_dialog_comp_ev_buf;
skb_len = hdd_get_twt_event_len();
reply_skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
skb_len);
if (!reply_skb) {
hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
ret = -ENOMEM;
goto err;
}
status = hdd_twt_terminate_pack_resp_nlmsg(reply_skb,
del_dialog_comp_ev_params);
if (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("Failed to pack nl del dialog response");
ret = qdf_status_to_os_return(status);
goto err;
}
ret = wlan_cfg80211_vendor_cmd_reply(reply_skb);
err:
if (request)
osif_request_put(request);
if (ret && reply_skb)
kfree_skb(reply_skb);
return ret;
}
@@ -1513,43 +1462,6 @@ static int hdd_twt_terminate_session(struct hdd_adapter *adapter,
return ret;
}
/**
* hdd_twt_pause_dialog_comp_cb() - callback function
* to get twt pause command complete event
* @context: private context
* @params: Pointer to pause dialog complete event buffer
*
* Return: None
*/
static void
hdd_twt_pause_dialog_comp_cb(void *context,
struct wmi_twt_pause_dialog_complete_event_param *params)
{
struct osif_request *request;
struct twt_pause_dialog_comp_ev_priv *priv;
hdd_enter();
request = osif_request_get(context);
if (!request) {
hdd_err("Obsolete request");
return;
}
priv = osif_request_priv(request);
qdf_mem_copy(&priv->pause_dialog_comp_ev_buf, params, sizeof(*params));
osif_request_complete(request);
osif_request_put(request);
hdd_debug("TWT: pause dialog_id:%d, status:%d vdev_id %d peer mac_addr "
QDF_MAC_ADDR_FMT, params->dialog_id,
params->status, params->vdev_id,
QDF_MAC_ADDR_REF(params->peer_macaddr));
hdd_exit();
}
/**
* hdd_twt_nudge_dialog_comp_cb() - callback function
* to get twt nudge command complete event
@@ -1600,8 +1512,22 @@ static QDF_STATUS
hdd_twt_pause_pack_resp_nlmsg(struct sk_buff *reply_skb,
struct wmi_twt_pause_dialog_complete_event_param *params)
{
struct nlattr *config_attr;
int vendor_status;
if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
QCA_WLAN_TWT_SUSPEND)) {
hdd_err("TWT: Failed to put TWT operation");
return QDF_STATUS_E_FAILURE;
}
config_attr = nla_nest_start(reply_skb,
QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
if (!config_attr) {
hdd_err("TWT: nla_nest_start error");
return QDF_STATUS_E_INVAL;
}
if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_FLOW_ID,
params->dialog_id)) {
hdd_debug("TWT: Failed to put dialog_id");
@@ -1615,6 +1541,8 @@ hdd_twt_pause_pack_resp_nlmsg(struct sk_buff *reply_skb,
return QDF_STATUS_E_FAILURE;
}
nla_nest_end(reply_skb, config_attr);
return QDF_STATUS_SUCCESS;
}
@@ -1650,6 +1578,69 @@ hdd_twt_nudge_pack_resp_nlmsg(struct sk_buff *reply_skb,
return QDF_STATUS_SUCCESS;
}
/*
* hdd_twt_pause_dialog_comp_cb() - callback function
* to get twt pause command complete event
* @psoc: pointer to global psoc
* @params: Pointer to pause dialog complete event buffer
*
* Return: None
*/
static void
hdd_twt_pause_dialog_comp_cb(
struct wlan_objmgr_psoc *psoc,
struct wmi_twt_pause_dialog_complete_event_param *params)
{
struct hdd_adapter *adapter =
wlan_hdd_get_adapter_from_vdev(psoc, params->vdev_id);
struct wireless_dev *wdev;
struct hdd_context *hdd_ctx;
struct sk_buff *twt_vendor_event;
size_t data_len;
QDF_STATUS status;
hdd_enter();
if (!adapter) {
hdd_err("adapter is NULL");
return;
}
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
status = wlan_hdd_validate_context(hdd_ctx);
if (QDF_IS_STATUS_ERROR(status))
return;
wdev = adapter->dev->ieee80211_ptr;
hdd_debug("TWT: pause dialog_id:%d, status:%d vdev_id %d peer mac_addr "
QDF_MAC_ADDR_FMT, params->dialog_id,
params->status, params->vdev_id,
QDF_MAC_ADDR_REF(params->peer_macaddr));
data_len = hdd_get_twt_event_len() + nla_total_size(sizeof(u8));
data_len += NLA_HDRLEN;
twt_vendor_event = wlan_cfg80211_vendor_event_alloc(
hdd_ctx->wiphy, wdev, data_len,
QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT_INDEX,
GFP_KERNEL);
if (!twt_vendor_event) {
hdd_err("TWT: pause dialog alloc skb failed");
return;
}
status = hdd_twt_pause_pack_resp_nlmsg(twt_vendor_event, params);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("Failed to pack nl pause dialog response");
wlan_cfg80211_vendor_free_skb(twt_vendor_event);
}
wlan_cfg80211_vendor_event(twt_vendor_event, GFP_KERNEL);
hdd_exit();
}
/**
* hdd_send_twt_pause_dialog_cmd() - Send TWT pause dialog command to target
* @hdd_ctx: HDD Context
@@ -1661,71 +1652,16 @@ static
int hdd_send_twt_pause_dialog_cmd(struct hdd_context *hdd_ctx,
struct wmi_twt_pause_dialog_cmd_param *twt_params)
{
struct wmi_twt_pause_dialog_complete_event_param *comp_ev_params;
struct twt_pause_dialog_comp_ev_priv *priv;
static const struct osif_request_params osif_req_params = {
.priv_size = sizeof(*priv),
.timeout_ms = TWT_PAUSE_COMPLETE_TIMEOUT,
.dealloc = NULL,
};
struct osif_request *request;
struct sk_buff *reply_skb = NULL;
QDF_STATUS status;
void *cookie;
int skb_len;
int ret;
request = osif_request_alloc(&osif_req_params);
if (!request) {
hdd_err("twt osif request allocation failure");
ret = -ENOMEM;
goto err;
}
cookie = osif_request_cookie(request);
int ret = 0;
status = sme_pause_dialog_cmd(hdd_ctx->mac_handle,
hdd_twt_pause_dialog_comp_cb,
twt_params, cookie);
twt_params);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("Failed to send pause dialog command");
ret = qdf_status_to_os_return(status);
goto err;
}
ret = osif_request_wait_for_response(request);
if (ret) {
hdd_err("twt: pause dialog req timedout");
ret = -ETIMEDOUT;
goto err;
}
priv = osif_request_priv(request);
comp_ev_params = &priv->pause_dialog_comp_ev_buf;
skb_len = hdd_get_twt_event_len();
reply_skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
skb_len);
if (!reply_skb) {
hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
ret = -ENOMEM;
goto err;
}
status = hdd_twt_pause_pack_resp_nlmsg(reply_skb, comp_ev_params);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("Failed to pack nl pause dialog response");
ret = qdf_status_to_os_return(status);
goto err;
}
ret = wlan_cfg80211_vendor_cmd_reply(reply_skb);
err:
if (request)
osif_request_put(request);
if (ret && reply_skb)
kfree_skb(reply_skb);
return ret;
}
@@ -1947,43 +1883,6 @@ static int hdd_twt_nudge_session(struct hdd_adapter *adapter,
return ret;
}
/**
* hdd_twt_resume_dialog_comp_cb() - callback function
* to get twt resume command complete event
* @context: private context
* @params: Pointer to resume dialog complete event buffer
*
* Return: None
*/
static void
hdd_twt_resume_dialog_comp_cb(void *context,
struct wmi_twt_resume_dialog_complete_event_param *params)
{
struct osif_request *request;
struct twt_resume_dialog_comp_ev_priv *priv;
hdd_enter();
request = osif_request_get(context);
if (!request) {
hdd_err("Obsolete request");
return;
}
priv = osif_request_priv(request);
qdf_mem_copy(&priv->res_dialog_comp_ev_buf, params, sizeof(*params));
osif_request_complete(request);
osif_request_put(request);
hdd_debug("TWT: resume dialog_id:%d status:%d vdev_id %d peer mac_addr "
QDF_MAC_ADDR_FMT, params->dialog_id,
params->status, params->vdev_id,
QDF_MAC_ADDR_REF(params->peer_macaddr));
hdd_exit();
}
/**
* hdd_twt_resume_pack_resp_nlmsg() - pack the skb with
* firmware response for twt resume command
@@ -1997,8 +1896,22 @@ static QDF_STATUS
hdd_twt_resume_pack_resp_nlmsg(struct sk_buff *reply_skb,
struct wmi_twt_resume_dialog_complete_event_param *params)
{
struct nlattr *config_attr;
int vendor_status;
if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
QCA_WLAN_TWT_RESUME)) {
hdd_err("TWT: Failed to put TWT operation");
return QDF_STATUS_E_FAILURE;
}
config_attr = nla_nest_start(reply_skb,
QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_PARAMS);
if (!config_attr) {
hdd_err("TWT: nla_nest_start error");
return QDF_STATUS_E_INVAL;
}
if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_RESUME_FLOW_ID,
params->dialog_id)) {
hdd_debug("TWT: Failed to put dialog_id");
@@ -2012,9 +1925,71 @@ hdd_twt_resume_pack_resp_nlmsg(struct sk_buff *reply_skb,
return QDF_STATUS_E_FAILURE;
}
nla_nest_end(reply_skb, config_attr);
return QDF_STATUS_SUCCESS;
}
/**
* hdd_twt_resume_dialog_comp_cb() - callback function
* to get twt resume command complete event
* @psoc: Pointer to global psoc
* @vdev_id: Vdev id
* @params: Pointer to resume dialog complete event buffer
*
* Return: None
*/
static void hdd_twt_resume_dialog_comp_cb(
struct wlan_objmgr_psoc *psoc,
struct wmi_twt_resume_dialog_complete_event_param *params)
{
struct hdd_adapter *adapter =
wlan_hdd_get_adapter_from_vdev(psoc, params->vdev_id);
struct hdd_context *hdd_ctx;
struct wireless_dev *wdev;
struct sk_buff *twt_vendor_event;
size_t data_len;
QDF_STATUS status;
hdd_enter();
if (!adapter) {
hdd_err("adapter is NULL");
return;
}
hdd_ctx = WLAN_HDD_GET_CTX(adapter);
status = wlan_hdd_validate_context(hdd_ctx);
if (QDF_IS_STATUS_ERROR(status))
return;
wdev = adapter->dev->ieee80211_ptr;
hdd_debug("TWT: resume dialog_id:%d status:%d vdev_id %d peer mac_addr "
QDF_MAC_ADDR_FMT, params->dialog_id,
params->status, params->vdev_id,
QDF_MAC_ADDR_REF(params->peer_macaddr));
data_len = hdd_get_twt_event_len() + nla_total_size(sizeof(u8));
data_len += NLA_HDRLEN;
twt_vendor_event = wlan_cfg80211_vendor_event_alloc(
hdd_ctx->wiphy, wdev, data_len,
QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT_INDEX,
GFP_KERNEL);
if (!twt_vendor_event) {
hdd_err("TWT: skb alloc failed");
return;
}
status = hdd_twt_resume_pack_resp_nlmsg(twt_vendor_event, params);
if (QDF_IS_STATUS_ERROR(status))
hdd_err("Failed to pack nl resume dialog response");
wlan_cfg80211_vendor_event(twt_vendor_event, GFP_KERNEL);
hdd_exit();
}
/**
* hdd_send_twt_resume_dialog_cmd() - Send TWT resume dialog command to target
* @hdd_ctx: HDD Context
@@ -2026,71 +2001,16 @@ static int
hdd_send_twt_resume_dialog_cmd(struct hdd_context *hdd_ctx,
struct wmi_twt_resume_dialog_cmd_param *twt_params)
{
struct wmi_twt_resume_dialog_complete_event_param *comp_ev_params;
struct twt_resume_dialog_comp_ev_priv *priv;
static const struct osif_request_params osif_req_params = {
.priv_size = sizeof(*priv),
.timeout_ms = TWT_RESUME_COMPLETE_TIMEOUT,
.dealloc = NULL,
};
struct osif_request *request;
struct sk_buff *reply_skb = NULL;
QDF_STATUS status;
void *cookie;
int skb_len;
int ret;
request = osif_request_alloc(&osif_req_params);
if (!request) {
hdd_err("twt osif request allocation failure");
ret = -ENOMEM;
goto err;
}
cookie = osif_request_cookie(request);
int ret = 0;
status = sme_resume_dialog_cmd(hdd_ctx->mac_handle,
hdd_twt_resume_dialog_comp_cb,
twt_params, cookie);
twt_params);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("Failed to send resume dialog command");
ret = qdf_status_to_os_return(status);
goto err;
}
ret = osif_request_wait_for_response(request);
if (ret) {
hdd_err("twt: resume dialog req timedout");
ret = -ETIMEDOUT;
goto err;
}
priv = osif_request_priv(request);
comp_ev_params = &priv->res_dialog_comp_ev_buf;
skb_len = hdd_get_twt_event_len();
reply_skb = wlan_cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
skb_len);
if (!reply_skb) {
hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
ret = -ENOMEM;
goto err;
}
status = hdd_twt_resume_pack_resp_nlmsg(reply_skb, comp_ev_params);
if (QDF_IS_STATUS_ERROR(status)) {
hdd_err("Failed to pack nl resume dialog response");
ret = qdf_status_to_os_return(status);
goto err;
}
ret = wlan_cfg80211_vendor_cmd_reply(reply_skb);
err:
if (request)
osif_request_put(request);
if (ret && reply_skb)
kfree_skb(reply_skb);
return ret;
}
@@ -2443,8 +2363,8 @@ QDF_STATUS hdd_send_twt_disable_cmd(struct hdd_context *hdd_ctx)
/**
* hdd_twt_enable_comp_cb() - TWT enable complete event callback
* @hdd_handle: opaque handle for the global HDD Context
* @twt_event: TWT event data received from the target
* @hdd_handle: Pointer to opaque HDD handle
* @params: Pointer to TWT enable completion parameters
*
* Return: None
*/
@@ -2455,10 +2375,6 @@ hdd_twt_enable_comp_cb(hdd_handle_t hdd_handle,
struct hdd_context *hdd_ctx = hdd_handle_to_context(hdd_handle);
enum twt_status prev_state;
if (!hdd_ctx) {
hdd_err("TWT: Invalid HDD Context");
return;
}
prev_state = hdd_ctx->twt_state;
if (params->status == WMI_HOST_ENABLE_TWT_STATUS_OK ||
params->status == WMI_HOST_ENABLE_TWT_STATUS_ALREADY_ENABLED) {
@@ -2495,16 +2411,10 @@ hdd_twt_disable_comp_cb(hdd_handle_t hdd_handle)
enum twt_status prev_state;
QDF_STATUS status;
if (!hdd_ctx) {
hdd_err("TWT: Invalid HDD Context");
return;
}
prev_state = hdd_ctx->twt_state;
/* Do not change the state for role specific disables */
if (hdd_ctx->twt_state == TWT_DISABLE_REQUESTED) {
if (hdd_ctx->twt_state == TWT_DISABLE_REQUESTED)
hdd_ctx->twt_state = TWT_DISABLED;
}
hdd_debug("TWT: State transitioned from %d to %d",
prev_state, hdd_ctx->twt_state);
@@ -2567,7 +2477,7 @@ void wlan_hdd_twt_init(struct hdd_context *hdd_ctx)
hdd_ctx->twt_state = TWT_INIT;
sme_init_twt_complete_cb(hdd_ctx->mac_handle);
sme_clear_twt_complete_cb(hdd_ctx->mac_handle);
twt_cb.twt_enable_cb = hdd_twt_enable_comp_cb;
twt_cb.twt_disable_cb = hdd_twt_disable_comp_cb;
twt_cb.twt_add_dialog_cb = hdd_twt_add_dialog_comp_cb;
@@ -2582,7 +2492,7 @@ void wlan_hdd_twt_init(struct hdd_context *hdd_ctx)
status = qdf_event_create(&hdd_ctx->twt_disable_comp_evt);
if (QDF_IS_STATUS_ERROR(status)) {
sme_deregister_twt_callbacks(hdd_ctx->mac_handle);
sme_clear_twt_complete_cb(hdd_ctx->mac_handle);
hdd_err("twt_disable_comp_evt init failed");
return;
}
@@ -2598,8 +2508,8 @@ void wlan_hdd_twt_deinit(struct hdd_context *hdd_ctx)
if (QDF_IS_STATUS_ERROR(status))
hdd_err("Failed to destroy twt_disable_comp_evt");
status = sme_deregister_twt_callbacks(hdd_ctx->mac_handle);
if (!QDF_IS_STATUS_SUCCESS(status))
status = sme_clear_twt_complete_cb(hdd_ctx->mac_handle);
if (QDF_IS_STATUS_ERROR(status))
hdd_err("De-register of twt disable cb failed: %d", status);
hdd_ctx->twt_state = TWT_CLOSED;

View File

@@ -3697,13 +3697,13 @@ sme_test_config_twt_terminate(struct wmi_twt_del_dialog_param *params);
QDF_STATUS sme_test_config_twt_setup(struct wmi_twt_add_dialog_param *params);
/**
* sme_init_twt_complete_cb() - Initialize TWT callbacks
* sme_clear_twt_complete_cb() - Initialize TWT callbacks
* @mac_handle: MAC handle
*
* Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes
* on failure
*/
QDF_STATUS sme_init_twt_complete_cb(mac_handle_t mac_handle);
QDF_STATUS sme_clear_twt_complete_cb(mac_handle_t mac_handle);
/**
* sme_register_twt_callbacks() - TWT enable registrar
@@ -3734,31 +3734,25 @@ QDF_STATUS sme_add_dialog_cmd(mac_handle_t mac_handle,
* @mac_handle: MAC handle
* @twt_del_dialog_cb: Function callback to handle del_dialog event
* @twt_params: TWT del dialog parameters
* @context: os_if_request cookie
*
* Return: QDF Status
*/
QDF_STATUS sme_del_dialog_cmd(mac_handle_t mac_handle,
twt_del_dialog_cb del_dialog_cb,
struct wmi_twt_del_dialog_param *twt_params,
void *context);
struct wmi_twt_del_dialog_param *twt_params);
/**
* sme_pause_dialog_cmd() - Register callback and send TWT pause dialog
* command to firmware
* @mac_handle: MAC handle
* @twt_pause_dialog_cb: Function callback to handle pause_dialog event
* @twt_params: TWT pause dialog parameters
* @context: os_if_request cookie
*
* Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes
* on failure
*/
QDF_STATUS
sme_pause_dialog_cmd(mac_handle_t mac_handle,
twt_pause_dialog_cb pause_dialog_cb,
struct wmi_twt_pause_dialog_cmd_param *twt_params,
void *context);
struct wmi_twt_pause_dialog_cmd_param *twt_params);
/**
* sme_nudge_dialog_cmd() - Register callback and send TWT nudge dialog
@@ -3781,27 +3775,14 @@ sme_nudge_dialog_cmd(mac_handle_t mac_handle,
* sme_resume_dialog_cmd() - Register callback and send TWT resume dialog
* command to firmware
* @mac_handle: MAC handle
* @twt_resume_dialog_cb: Function callback to handle resume_dialog event
* @twt_params: TWT resume dialog parameters
* @context: os_if_request cookie
*
* Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes
* on failure
*/
QDF_STATUS
sme_resume_dialog_cmd(mac_handle_t mac_handle,
twt_resume_dialog_cb resume_dialog_cb,
struct wmi_twt_resume_dialog_cmd_param *twt_params,
void *context);
/**
* sme_deregister_twt_callbacks() - TWT enable deregistrar
* @mac_handle: Opaque handle to the global MAC context
*
* Return: QDF Status
*/
QDF_STATUS sme_deregister_twt_callbacks(mac_handle_t mac_handle);
struct wmi_twt_resume_dialog_cmd_param *twt_params);
#else
static inline

View File

@@ -147,7 +147,7 @@ typedef void (*sme_send_oem_data_rsp_msg)(struct oem_data_rsp *);
#ifdef WLAN_SUPPORT_TWT
/**
* typedef twt_enable_cb - TWT enable callback signature.
* @hdd_handle: Opaque handle to the HDD context
* @hdd_handle: Opaque HDD handle
* @params: TWT enable complete event parameters.
*/
typedef
@@ -156,35 +156,35 @@ void (*twt_enable_cb)(hdd_handle_t hdd_handle,
/**
* typedef twt_disable_cb - TWT enable callback signature.
* @hdd_handle: Opaque handle to the HDD context
* @hdd_handle: Opaque HDD handle
*/
typedef void (*twt_disable_cb)(hdd_handle_t hdd_handle);
/**
* typedef twt_add_dialog_cb - TWT add dialog callback signature.
* @hdd_handle: Opaque handle to the HDD context
* @add_dialog_event: pointer to event buf containing twt response parameters
* @psoc: Pointer to global psoc
* @add_dialog_evt: pointer to event buf containing twt response parameters
*/
typedef void (*twt_add_dialog_cb)(hdd_handle_t hdd_handle,
struct twt_add_dialog_complete_event *add_dialog_event);
typedef
void (*twt_add_dialog_cb)(struct wlan_objmgr_psoc *psoc,
struct twt_add_dialog_complete_event *add_dialog_evt);
/**
* typedef twt_del_dialog_cb - TWT delete dialog callback signature.
* @context: Opaque context that the client can use to associate the
* callback with the request.
* @psoc: Pointer to global psoc
* @params: TWT delete dialog complete event parameters.
*/
typedef void (*twt_del_dialog_cb)(void *context,
struct wmi_twt_del_dialog_complete_event_param *params);
typedef void (*twt_del_dialog_cb)(
struct wlan_objmgr_psoc *psoc,
struct wmi_twt_del_dialog_complete_event_param *params);
/**
* typedef twt_pause_dialog_cb - TWT pause dialog callback signature.
* @context: Opaque context that the client can use to associate the
* callback with the request.
* @psoc: Pointer to global psoc
* @params: TWT pause dialog complete event parameters.
*/
typedef
void (*twt_pause_dialog_cb)(void *context,
void (*twt_pause_dialog_cb)(struct wlan_objmgr_psoc *psoc,
struct wmi_twt_pause_dialog_complete_event_param *params);
/**
@@ -199,12 +199,11 @@ void (*twt_nudge_dialog_cb)(void *context,
/**
* typedef twt_resume_dialog_cb - TWT resume dialog callback signature.
* @context: Opaque context that the client can use to associate the
* callback with the request.
* @psoc: Pointer to global psoc
* @params: TWT resume dialog complete event parameters.
*/
typedef
void (*twt_resume_dialog_cb)(void *context,
void (*twt_resume_dialog_cb)(struct wlan_objmgr_psoc *psoc,
struct wmi_twt_resume_dialog_complete_event_param *params);
/**
@@ -220,13 +219,13 @@ struct twt_callbacks {
void (*twt_enable_cb)(hdd_handle_t hdd_handle,
struct wmi_twt_enable_complete_event_param *params);
void (*twt_disable_cb)(hdd_handle_t hdd_handle);
void (*twt_add_dialog_cb)(hdd_handle_t hdd_handle,
void (*twt_add_dialog_cb)(struct wlan_objmgr_psoc *psoc,
struct twt_add_dialog_complete_event *add_dialog_event);
void (*twt_del_dialog_cb)(void *context,
void (*twt_del_dialog_cb)(struct wlan_objmgr_psoc *psoc,
struct wmi_twt_del_dialog_complete_event_param *params);
void (*twt_pause_dialog_cb)(void *context,
void (*twt_pause_dialog_cb)(struct wlan_objmgr_psoc *psoc,
struct wmi_twt_pause_dialog_complete_event_param *params);
void (*twt_resume_dialog_cb)(void *context,
void (*twt_resume_dialog_cb)(struct wlan_objmgr_psoc *psoc,
struct wmi_twt_resume_dialog_complete_event_param *params);
};
#endif
@@ -443,10 +442,7 @@ struct sme_context {
twt_pause_dialog_cb twt_pause_dialog_cb;
twt_nudge_dialog_cb twt_nudge_dialog_cb;
twt_resume_dialog_cb twt_resume_dialog_cb;
void *twt_del_dialog_context;
void *twt_pause_dialog_context;
void *twt_nudge_dialog_context;
void *twt_resume_dialog_context;
#endif
#ifdef FEATURE_WLAN_APF
apf_get_offload_cb apf_get_offload_cb;

View File

@@ -2100,7 +2100,7 @@ sme_process_twt_add_dialog_event(struct mac_context *mac,
callback = mac->sme.twt_add_dialog_cb;
if (callback)
callback(mac->hdd_handle, add_dialog_event);
callback(mac->psoc, add_dialog_event);
}
/**
@@ -2116,13 +2116,10 @@ sme_process_twt_del_dialog_event(struct mac_context *mac,
struct wmi_twt_del_dialog_complete_event_param *param)
{
twt_del_dialog_cb callback;
void *context;
callback = mac->sme.twt_del_dialog_cb;
context = mac->sme.twt_del_dialog_context;
mac->sme.twt_del_dialog_cb = NULL;
if (callback)
callback(context, param);
callback(mac->psoc, param);
}
/**
@@ -2138,12 +2135,10 @@ sme_process_twt_pause_dialog_event(struct mac_context *mac,
struct wmi_twt_pause_dialog_complete_event_param *param)
{
twt_pause_dialog_cb callback;
void *context;
callback = mac->sme.twt_pause_dialog_cb;
context = mac->sme.twt_pause_dialog_context;
if (callback)
callback(context, param);
callback(mac->psoc, param);
}
/**
@@ -2181,12 +2176,10 @@ sme_process_twt_resume_dialog_event(struct mac_context *mac,
struct wmi_twt_resume_dialog_complete_event_param *param)
{
twt_resume_dialog_cb callback;
void *context;
callback = mac->sme.twt_resume_dialog_cb;
context = mac->sme.twt_resume_dialog_context;
if (callback)
callback(context, param);
callback(mac->psoc, param);
}
#else
@@ -13974,7 +13967,7 @@ sme_test_config_twt_terminate(struct wmi_twt_del_dialog_param *params)
return wma_twt_process_del_dialog(wma_handle, params);
}
QDF_STATUS sme_init_twt_complete_cb(mac_handle_t mac_handle)
QDF_STATUS sme_clear_twt_complete_cb(mac_handle_t mac_handle)
{
QDF_STATUS status;
struct mac_context *mac = MAC_CONTEXT(mac_handle);
@@ -14014,20 +14007,6 @@ QDF_STATUS sme_register_twt_callbacks(mac_handle_t mac_handle,
return status;
}
QDF_STATUS sme_deregister_twt_callbacks(mac_handle_t mac_handle)
{
struct twt_callbacks twt_cb;
twt_cb.twt_enable_cb = NULL;
twt_cb.twt_add_dialog_cb = NULL;
twt_cb.twt_del_dialog_cb = NULL;
twt_cb.twt_pause_dialog_cb = NULL;
twt_cb.twt_resume_dialog_cb = NULL;
twt_cb.twt_disable_cb = NULL;
return sme_register_twt_callbacks(mac_handle, &twt_cb);
}
QDF_STATUS sme_add_dialog_cmd(mac_handle_t mac_handle,
twt_add_dialog_cb twt_add_dialog_cb,
struct wmi_twt_add_dialog_param *twt_params)
@@ -14079,8 +14058,7 @@ QDF_STATUS sme_add_dialog_cmd(mac_handle_t mac_handle,
QDF_STATUS sme_del_dialog_cmd(mac_handle_t mac_handle,
twt_del_dialog_cb del_dialog_cb,
struct wmi_twt_del_dialog_param *twt_params,
void *context)
struct wmi_twt_del_dialog_param *twt_params)
{
struct mac_context *mac = MAC_CONTEXT(mac_handle);
struct scheduler_msg twt_msg = {0};
@@ -14109,7 +14087,6 @@ QDF_STATUS sme_del_dialog_cmd(mac_handle_t mac_handle,
/* Serialize the req through MC thread */
mac->sme.twt_del_dialog_cb = del_dialog_cb;
mac->sme.twt_del_dialog_context = context;
twt_msg.bodyptr = cmd_params;
twt_msg.type = WMA_TWT_DEL_DIALOG_REQUEST;
sme_release_global_lock(&mac->sme);
@@ -14130,9 +14107,7 @@ QDF_STATUS sme_del_dialog_cmd(mac_handle_t mac_handle,
QDF_STATUS
sme_pause_dialog_cmd(mac_handle_t mac_handle,
twt_pause_dialog_cb pause_dialog_cb,
struct wmi_twt_pause_dialog_cmd_param *twt_params,
void *context)
struct wmi_twt_pause_dialog_cmd_param *twt_params)
{
struct mac_context *mac = MAC_CONTEXT(mac_handle);
struct wmi_twt_pause_dialog_cmd_param *cmd_params;
@@ -14160,8 +14135,6 @@ sme_pause_dialog_cmd(mac_handle_t mac_handle,
}
/* Serialize the req through MC thread */
mac->sme.twt_pause_dialog_cb = pause_dialog_cb;
mac->sme.twt_pause_dialog_context = context;
twt_msg.bodyptr = cmd_params;
twt_msg.type = WMA_TWT_PAUSE_DIALOG_REQUEST;
sme_release_global_lock(&mac->sme);
@@ -14243,9 +14216,7 @@ sme_nudge_dialog_cmd(mac_handle_t mac_handle,
QDF_STATUS
sme_resume_dialog_cmd(mac_handle_t mac_handle,
twt_resume_dialog_cb resume_dialog_cb,
struct wmi_twt_resume_dialog_cmd_param *twt_params,
void *context)
struct wmi_twt_resume_dialog_cmd_param *twt_params)
{
struct mac_context *mac = MAC_CONTEXT(mac_handle);
struct wmi_twt_resume_dialog_cmd_param *cmd_params;
@@ -14273,8 +14244,6 @@ sme_resume_dialog_cmd(mac_handle_t mac_handle,
}
/* Serialize the req through MC thread */
mac->sme.twt_resume_dialog_cb = resume_dialog_cb;
mac->sme.twt_resume_dialog_context = context;
twt_msg.bodyptr = cmd_params;
twt_msg.type = WMA_TWT_RESUME_DIALOG_REQUEST;
sme_release_global_lock(&mac->sme);