From d26e1e29f73ed7014e68b4e0eb0bd2ad3e35f28e Mon Sep 17 00:00:00 2001 From: Pragaspathi Thilagaraj Date: Thu, 3 Dec 2020 04:13:27 +0530 Subject: [PATCH] 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 --- core/hdd/src/wlan_hdd_cfg80211.c | 7 +- core/hdd/src/wlan_hdd_twt.c | 580 +++++++++++++------------------ core/sme/inc/sme_api.h | 29 +- core/sme/inc/sme_internal.h | 42 +-- core/sme/src/common/sme_api.c | 47 +-- 5 files changed, 283 insertions(+), 422 deletions(-) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 16aec4f0c4d1..3050d1c501ef 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -4018,10 +4018,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. diff --git a/core/hdd/src/wlan_hdd_twt.c b/core/hdd/src/wlan_hdd_twt.c index 78e8589c9757..45abfcfb5bc5 100644 --- a/core/hdd/src/wlan_hdd_twt.c +++ b/core/hdd/src/wlan_hdd_twt.c @@ -36,12 +36,8 @@ #include "cfg_ucfg_api.h" #include -#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 }, @@ -1131,27 +1083,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) { @@ -1175,25 +1134,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); } /** @@ -1319,8 +1282,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"); @@ -1334,44 +1311,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; } /** @@ -1385,73 +1390,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; } @@ -1517,43 +1466,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 @@ -1604,8 +1516,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"); @@ -1619,6 +1545,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; } @@ -1654,6 +1582,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 @@ -1665,71 +1656,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; } @@ -1951,43 +1887,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 @@ -2001,8 +1900,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"); @@ -2016,9 +1929,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 @@ -2030,71 +2005,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; } @@ -2461,8 +2381,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 */ @@ -2473,10 +2393,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) { @@ -2513,16 +2429,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); @@ -2585,7 +2495,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; @@ -2600,7 +2510,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; } @@ -2616,8 +2526,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; diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index c7ed6b680002..2906c0a09bd8 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -3652,13 +3652,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 @@ -3689,31 +3689,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 @@ -3736,27 +3730,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 diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index 54727f1723e5..556fa60060ed 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -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; diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 5cf15ea41580..85533362753b 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -2065,7 +2065,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); } /** @@ -2081,13 +2081,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); } /** @@ -2103,12 +2100,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); } /** @@ -2146,12 +2141,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 @@ -14477,7 +14470,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); @@ -14517,20 +14510,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) @@ -14584,8 +14563,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}; @@ -14616,7 +14594,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); @@ -14637,9 +14614,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; @@ -14669,8 +14644,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); @@ -14752,9 +14725,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; @@ -14784,8 +14755,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);