From e5f614db0e8dba39626d2c91f04495f461c1daf3 Mon Sep 17 00:00:00 2001 From: Rajasekaran Kalidoss Date: Tue, 22 Dec 2020 21:23:32 +0530 Subject: [PATCH] qcacld-3.0: Change TWT nudge to asynchronous command Change TWT nudge command to be asynchronous. Handle wake time tsf field in the nudge command response. Change-Id: I22c75a42bf60f52f52d7d7fe19f408ebb55f360a CRs-Fixed: 2847173 --- components/mlme/core/src/wlan_mlme_twt_api.c | 24 +- core/hdd/src/wlan_hdd_twt.c | 224 +++++++++---------- core/sme/inc/sme_api.h | 6 +- core/sme/inc/sme_internal.h | 9 +- core/sme/src/common/sme_api.c | 21 +- 5 files changed, 129 insertions(+), 155 deletions(-) diff --git a/components/mlme/core/src/wlan_mlme_twt_api.c b/components/mlme/core/src/wlan_mlme_twt_api.c index 4c5facb2071a..5bfbf083081e 100644 --- a/components/mlme/core/src/wlan_mlme_twt_api.c +++ b/components/mlme/core/src/wlan_mlme_twt_api.c @@ -202,10 +202,14 @@ bool mlme_is_twt_setup_done(struct wlan_objmgr_psoc *psoc, } for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) { - if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id) { + if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id || + dialog_id == WLAN_ALL_SESSIONS_DIALOG_ID) { is_setup_done = peer_priv->twt_ctx.session_info[i].setup_done; - break; + + if (dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID || + is_setup_done) + break; } } @@ -295,7 +299,8 @@ void mlme_set_twt_session_state(struct wlan_objmgr_psoc *psoc, mlme_debug("set_state:%d for dialog_id:%d", state, dialog_id); for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) { - if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id) { + if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id || + dialog_id == WLAN_ALL_SESSIONS_DIALOG_ID) { peer_priv->twt_ctx.session_info[i].state = state; break; } @@ -508,14 +513,21 @@ bool mlme_twt_is_command_in_progress(struct wlan_objmgr_psoc *psoc, for (i = 0; i < peer_priv->twt_ctx.num_twt_sessions; i++) { active_cmd = peer_priv->twt_ctx.session_info[i].active_cmd; - if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id) { + if (peer_priv->twt_ctx.session_info[i].dialog_id == dialog_id || + dialog_id == WLAN_ALL_SESSIONS_DIALOG_ID) { if (cmd == WLAN_TWT_ANY) { is_command_in_progress = (active_cmd != WLAN_TWT_NONE); - break; + + if (dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID || + is_command_in_progress) + break; } else { is_command_in_progress = (active_cmd == cmd); - break; + + if (dialog_id != WLAN_ALL_SESSIONS_DIALOG_ID || + is_command_in_progress) + break; } } } diff --git a/core/hdd/src/wlan_hdd_twt.c b/core/hdd/src/wlan_hdd_twt.c index 049d10766c5a..0124cdfb8061 100644 --- a/core/hdd/src/wlan_hdd_twt.c +++ b/core/hdd/src/wlan_hdd_twt.c @@ -38,7 +38,6 @@ #include #define TWT_DISABLE_COMPLETE_TIMEOUT 4000 -#define TWT_NUDGE_COMPLETE_TIMEOUT 4000 #define TWT_FLOW_TYPE_ANNOUNCED 0 #define TWT_FLOW_TYPE_UNANNOUNCED 1 @@ -50,18 +49,6 @@ #define TWT_MAX_NEXT_TWT_SIZE 3 #define TWT_ALL_SESSIONS_DIALOG_ID 255 -/** - * 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 - * - * This TWT nudge dialog private structure is registered with os_if to - * retrieve the TWT nudge dialog response event buffer. - */ -struct twt_nudge_dialog_comp_ev_priv { - struct wmi_twt_nudge_dialog_complete_event_param - nudge_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 }, @@ -1643,39 +1630,119 @@ static int hdd_twt_terminate_session(struct hdd_adapter *adapter, } /** + * hdd_twt_nudge_pack_resp_nlmsg() - pack the skb with + * firmware response for twt nudge command + * @reply_skb: skb to store the response + * @params: Pointer to nudge dialog complete event buffer + * + * Return: QDF_STATUS_SUCCESS on Success, QDF_STATUS_E_FAILURE + * on failure + */ +static QDF_STATUS +hdd_twt_nudge_pack_resp_nlmsg(struct sk_buff *reply_skb, + struct wmi_twt_nudge_dialog_complete_event_param *params) +{ + struct nlattr *config_attr; + int vendor_status; + uint64_t tsf_val; + + if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION, + QCA_WLAN_TWT_NUDGE)) { + hdd_err("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("nla_nest_start error"); + return QDF_STATUS_E_INVAL; + } + + if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, + params->dialog_id)) { + hdd_debug("Failed to put dialog_id"); + return QDF_STATUS_E_FAILURE; + } + + tsf_val = params->next_twt_tsf_us_hi; + tsf_val = (tsf_val << 32) | params->next_twt_tsf_us_lo; + if (hdd_wlan_nla_put_u64(reply_skb, + QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_WAKE_TIME_TSF, + tsf_val)) { + hdd_err("get_params failed to put TSF Value"); + return QDF_STATUS_E_INVAL; + } + + vendor_status = + wmi_twt_nudge_status_to_vendor_twt_status(params->status); + if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS, + vendor_status)) { + hdd_err("Failed to put QCA_WLAN_TWT_NUDGE status"); + return QDF_STATUS_E_FAILURE; + } + + nla_nest_end(reply_skb, config_attr); + + return QDF_STATUS_SUCCESS; +} + +/* * hdd_twt_nudge_dialog_comp_cb() - callback function * to get twt nudge command complete event - * @context: private context + * @psoc: Pointer to global psoc * @params: Pointer to nudge dialog complete event buffer * * Return: None */ -static void -hdd_twt_nudge_dialog_comp_cb(void *context, - struct wmi_twt_nudge_dialog_complete_event_param *params) +static void hdd_twt_nudge_dialog_comp_cb( + struct wlan_objmgr_psoc *psoc, + struct wmi_twt_nudge_dialog_complete_event_param *params) { - struct osif_request *request; - struct twt_nudge_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 (hdd_validate_adapter(adapter)) return; - } - priv = osif_request_priv(request); + hdd_ctx = WLAN_HDD_GET_CTX(adapter); - priv->nudge_dialog_comp_ev_buf = *params; - osif_request_complete(request); - osif_request_put(request); + wdev = adapter->dev->ieee80211_ptr; - hdd_debug("TWT: nudge dialog_id:%d, status:%d vdev_id %d peer mac_addr " + hdd_debug("Nudge 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)) + + nla_total_size(sizeof(u64)); + 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("Nudge dialog alloc skb failed"); + return; + } + + status = hdd_twt_nudge_pack_resp_nlmsg(twt_vendor_event, params); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Failed to pack nl nudge dialog response %d", status); + wlan_cfg80211_vendor_free_skb(twt_vendor_event); + } + + wlan_cfg80211_vendor_event(twt_vendor_event, GFP_KERNEL); + hdd_exit(); } @@ -1726,38 +1793,6 @@ hdd_twt_pause_pack_resp_nlmsg(struct sk_buff *reply_skb, return QDF_STATUS_SUCCESS; } -/** - * hdd_twt_nudge_pack_resp_nlmsg() - pack the skb with - * firmware response for twt nudge command - * @reply_skb: skb to store the response - * @params: Pointer to nudge dialog complete event buffer - * - * Return: QDF_STATUS_SUCCESS on Success, QDF_STATUS_E_FAILURE - * on failure - */ -static QDF_STATUS -hdd_twt_nudge_pack_resp_nlmsg(struct sk_buff *reply_skb, - struct wmi_twt_nudge_dialog_complete_event_param *params) -{ - int vendor_status; - - if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_NUDGE_FLOW_ID, - params->dialog_id)) { - hdd_debug("TWT: Failed to put dialog_id"); - return QDF_STATUS_E_FAILURE; - } - - vendor_status = - wmi_twt_nudge_status_to_vendor_twt_status(params->status); - if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_TWT_SETUP_STATUS, - vendor_status)) { - hdd_err("TWT: Failed to put QCA_WLAN_TWT_NUDGE status"); - return QDF_STATUS_E_FAILURE; - } - - return QDF_STATUS_SUCCESS; -} - /* * hdd_twt_pause_dialog_comp_cb() - callback function * to get twt pause command complete event @@ -1932,72 +1967,13 @@ static int hdd_send_twt_nudge_dialog_cmd(struct hdd_context *hdd_ctx, struct wmi_twt_nudge_dialog_cmd_param *twt_params) { - struct wmi_twt_nudge_dialog_complete_event_param *comp_ev_params; - struct twt_nudge_dialog_comp_ev_priv *priv; - static const struct osif_request_params osif_req_params = { - .priv_size = sizeof(*priv), - .timeout_ms = TWT_NUDGE_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); - - status = sme_nudge_dialog_cmd(hdd_ctx->mac_handle, - hdd_twt_nudge_dialog_comp_cb, - twt_params, cookie); - if (QDF_IS_STATUS_ERROR(status)) { + status = sme_nudge_dialog_cmd(hdd_ctx->mac_handle, twt_params); + if (QDF_IS_STATUS_ERROR(status)) hdd_err("Failed to send nudge dialog command"); - ret = qdf_status_to_os_return(status); - goto err; - } - ret = osif_request_wait_for_response(request); - if (ret) { - hdd_err("twt: nudge dialog req timedout"); - ret = -ETIMEDOUT; - goto err; - } - - priv = osif_request_priv(request); - comp_ev_params = &priv->nudge_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_nudge_pack_resp_nlmsg(reply_skb, comp_ev_params); - if (QDF_IS_STATUS_ERROR(status)) { - hdd_err("Failed to pack nl nudge 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; + return qdf_status_to_os_return(status); } /** @@ -3173,6 +3149,8 @@ void wlan_hdd_twt_init(struct hdd_context *hdd_ctx) twt_cb.twt_pause_dialog_cb = hdd_twt_pause_dialog_comp_cb; twt_cb.twt_resume_dialog_cb = hdd_twt_resume_dialog_comp_cb; twt_cb.twt_notify_cb = hdd_twt_notify_cb; + twt_cb.twt_nudge_dialog_cb = hdd_twt_nudge_dialog_comp_cb; + status = sme_register_twt_callbacks(hdd_ctx->mac_handle, &twt_cb); if (QDF_IS_STATUS_ERROR(status)) { hdd_err("Register twt enable complete failed"); diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 6fb16a744460..72b424ee21a1 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -3732,18 +3732,14 @@ sme_pause_dialog_cmd(mac_handle_t mac_handle, * sme_nudge_dialog_cmd() - Register callback and send TWT nudge dialog * command to firmware * @mac_handle: MAC handle - * @twt_nudge_dialog_cb: Function callback to handle nudge_dialog event * @twt_params: TWT nudge dialog parameters - * @context: os_if_request cookie * * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes * on failure */ QDF_STATUS sme_nudge_dialog_cmd(mac_handle_t mac_handle, - twt_nudge_dialog_cb nudge_dialog_cb, - struct wmi_twt_nudge_dialog_cmd_param *twt_params, - void *context); + struct wmi_twt_nudge_dialog_cmd_param *twt_params); /** * sme_resume_dialog_cmd() - Register callback and send TWT resume dialog diff --git a/core/sme/inc/sme_internal.h b/core/sme/inc/sme_internal.h index c13c8d846a62..2660e5070c4a 100644 --- a/core/sme/inc/sme_internal.h +++ b/core/sme/inc/sme_internal.h @@ -189,12 +189,11 @@ void (*twt_pause_dialog_cb)(struct wlan_objmgr_psoc *psoc, /** * typedef twt_nudge_dialog_cb - TWT nudge 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 nudge dialog complete event parameters. */ typedef -void (*twt_nudge_dialog_cb)(void *context, +void (*twt_nudge_dialog_cb)(struct wlan_objmgr_psoc *psoc, struct wmi_twt_nudge_dialog_complete_event_param *params); /** @@ -223,6 +222,7 @@ void (*twt_notify_cb)(struct wlan_objmgr_psoc *psoc, * @twt_pause_dialog_cb: TWT pause dialog completion callback * @twt_resume_dialog_cb: TWT resume dialog completion callback * @twt_notify_cb: TWT notify event callback + * @twt_nudge_dialog_cb: TWT nudge dialog completion callback */ struct twt_callbacks { void (*twt_enable_cb)(hdd_handle_t hdd_handle, @@ -238,6 +238,8 @@ struct twt_callbacks { struct wmi_twt_resume_dialog_complete_event_param *params); void (*twt_notify_cb)(struct wlan_objmgr_psoc *psoc, struct wmi_twt_notify_event_param *params); + void (*twt_nudge_dialog_cb)(struct wlan_objmgr_psoc *psoc, + struct wmi_twt_nudge_dialog_complete_event_param *params); }; #endif @@ -454,7 +456,6 @@ struct sme_context { twt_nudge_dialog_cb twt_nudge_dialog_cb; twt_resume_dialog_cb twt_resume_dialog_cb; twt_notify_cb twt_notify_cb; - void *twt_nudge_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 699dbd96972a..aac0b83b0e73 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -2182,7 +2182,6 @@ sme_process_twt_nudge_dialog_event(struct mac_context *mac, struct wmi_twt_nudge_dialog_complete_event_param *param) { twt_nudge_dialog_cb callback; - void *context; bool is_evt_allowed; is_evt_allowed = mlme_twt_is_command_in_progress( @@ -2195,11 +2194,8 @@ sme_process_twt_nudge_dialog_event(struct mac_context *mac, } callback = mac->sme.twt_nudge_dialog_cb; - context = mac->sme.twt_nudge_dialog_context; - mac->sme.twt_nudge_dialog_cb = NULL; if (callback) - callback(context, param); - + callback(mac->psoc, param); /* Reset the active TWT command to none */ mlme_set_twt_command_in_progress( mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr, @@ -14615,6 +14611,7 @@ QDF_STATUS sme_clear_twt_complete_cb(mac_handle_t mac_handle) mac->sme.twt_pause_dialog_cb = NULL; mac->sme.twt_resume_dialog_cb = NULL; mac->sme.twt_notify_cb = NULL; + mac->sme.twt_nudge_dialog_cb = NULL; sme_release_global_lock(&mac->sme); sme_debug("TWT: callbacks Initialized"); @@ -14638,6 +14635,7 @@ QDF_STATUS sme_register_twt_callbacks(mac_handle_t mac_handle, mac->sme.twt_resume_dialog_cb = twt_cb->twt_resume_dialog_cb; mac->sme.twt_disable_cb = twt_cb->twt_disable_cb; mac->sme.twt_notify_cb = twt_cb->twt_notify_cb; + mac->sme.twt_nudge_dialog_cb = twt_cb->twt_nudge_dialog_cb; sme_release_global_lock(&mac->sme); sme_debug("TWT: callbacks registered"); } @@ -14861,9 +14859,7 @@ sme_pause_dialog_cmd(mac_handle_t mac_handle, QDF_STATUS sme_nudge_dialog_cmd(mac_handle_t mac_handle, - twt_nudge_dialog_cb nudge_dialog_cb, - struct wmi_twt_nudge_dialog_cmd_param *twt_params, - void *context) + struct wmi_twt_nudge_dialog_cmd_param *twt_params) { struct mac_context *mac = MAC_CONTEXT(mac_handle); struct wmi_twt_nudge_dialog_cmd_param *cmd_params; @@ -14902,16 +14898,7 @@ sme_nudge_dialog_cmd(mac_handle_t mac_handle, return status; } - if (mac->sme.twt_nudge_dialog_cb) { - sme_release_global_lock(&mac->sme); - qdf_mem_free(cmd_params); - sme_err_rl("TWT: Command in progress - STATUS E_BUSY"); - return QDF_STATUS_E_BUSY; - } - /* Serialize the req through MC thread */ - mac->sme.twt_nudge_dialog_cb = nudge_dialog_cb; - mac->sme.twt_nudge_dialog_context = context; twt_msg.bodyptr = cmd_params; twt_msg.type = WMA_TWT_NUDGE_DIALOG_REQUEST; sme_release_global_lock(&mac->sme);