qcacld-3.0: Add support to handle twt_notify event
Add support to handle twt_notify event. Firmware can terminate a TWT session without a Host trigger due to internal reasons. In that case it sends an event to notify that it is again ready for a TWT session setup. Change-Id: I3508687cee93e16a26221a1bc7ad9c626a4f4523 CRs-Fixed: 2847158
This commit is contained in:

committed by
snandini

parent
ac5297a3df
commit
741def98ba
@@ -2310,6 +2310,79 @@ static int hdd_twt_resume_session(struct hdd_adapter *adapter,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_twt_notify_pack_nlmsg() - pack the skb with
|
||||
* twt notify event from firmware
|
||||
* @reply_skb: skb to store the response
|
||||
*
|
||||
* Return: QDF_STATUS_SUCCESS on Success, QDF_STATUS_E_FAILURE
|
||||
* on failure
|
||||
*/
|
||||
static QDF_STATUS
|
||||
hdd_twt_notify_pack_nlmsg(struct sk_buff *reply_skb)
|
||||
{
|
||||
if (nla_put_u8(reply_skb, QCA_WLAN_VENDOR_ATTR_CONFIG_TWT_OPERATION,
|
||||
QCA_WLAN_TWT_SETUP_READY_NOTIFY)) {
|
||||
hdd_err("Failed to put TWT notify operation");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_twt_notify_cb() - callback function
|
||||
* to get twt notify event
|
||||
* @psoc: Pointer to global psoc
|
||||
* @params: Pointer to notify param event buffer
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void
|
||||
hdd_twt_notify_cb(struct wlan_objmgr_psoc *psoc,
|
||||
struct wmi_twt_notify_event_param *params)
|
||||
{
|
||||
struct hdd_adapter *adapter =
|
||||
wlan_hdd_get_adapter_from_vdev(psoc, params->vdev_id);
|
||||
struct wireless_dev *wdev;
|
||||
struct sk_buff *twt_vendor_event;
|
||||
size_t data_len;
|
||||
QDF_STATUS status;
|
||||
|
||||
hdd_enter();
|
||||
|
||||
if (hdd_validate_adapter(adapter))
|
||||
return;
|
||||
|
||||
wdev = adapter->dev->ieee80211_ptr;
|
||||
|
||||
data_len = NLA_HDRLEN;
|
||||
data_len += nla_total_size(sizeof(u8));
|
||||
|
||||
twt_vendor_event = wlan_cfg80211_vendor_event_alloc(
|
||||
adapter->wdev.wiphy, wdev,
|
||||
data_len,
|
||||
QCA_NL80211_VENDOR_SUBCMD_CONFIG_TWT_INDEX,
|
||||
GFP_KERNEL);
|
||||
if (!twt_vendor_event) {
|
||||
hdd_err("Notify skb alloc failed");
|
||||
return;
|
||||
}
|
||||
|
||||
hdd_debug("Notify vdev_id %d", params->vdev_id);
|
||||
|
||||
status = hdd_twt_notify_pack_nlmsg(twt_vendor_event);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
hdd_err("Failed to pack nl notify event");
|
||||
wlan_cfg80211_vendor_free_skb(twt_vendor_event);
|
||||
return;
|
||||
}
|
||||
|
||||
wlan_cfg80211_vendor_event(twt_vendor_event, GFP_KERNEL);
|
||||
|
||||
hdd_exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_twt_configure - Process the TWT
|
||||
* operation in the received vendor command
|
||||
@@ -2720,6 +2793,7 @@ void wlan_hdd_twt_init(struct hdd_context *hdd_ctx)
|
||||
twt_cb.twt_del_dialog_cb = hdd_twt_del_dialog_comp_cb;
|
||||
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;
|
||||
status = sme_register_twt_callbacks(hdd_ctx->mac_handle, &twt_cb);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
hdd_err("Register twt enable complete failed");
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -250,7 +250,8 @@ enum eWniMsgTypes {
|
||||
eWNI_SME_TWT_PAUSE_DIALOG_EVENT = SIR_SME_MSG_TYPES_BEGIN + 167,
|
||||
eWNI_SME_TWT_RESUME_DIALOG_EVENT = SIR_SME_MSG_TYPES_BEGIN + 168,
|
||||
eWNI_SME_TWT_NUDGE_DIALOG_EVENT = SIR_SME_MSG_TYPES_BEGIN + 169,
|
||||
eWNI_SME_MSG_TYPES_END = SIR_SME_MSG_TYPES_BEGIN + 170
|
||||
eWNI_SME_TWT_NOTIFY_EVENT = SIR_SME_MSG_TYPES_BEGIN + 170,
|
||||
eWNI_SME_MSG_TYPES_END = SIR_SME_MSG_TYPES_BEGIN + 171
|
||||
};
|
||||
|
||||
typedef struct sAniCfgTxRateCtrs {
|
||||
|
@@ -3675,7 +3675,8 @@ QDF_STATUS sme_clear_twt_complete_cb(mac_handle_t mac_handle);
|
||||
* @mac_handle: MAC handle
|
||||
* @twt_cb: TWT callbacks
|
||||
*
|
||||
* Return: QDF Status
|
||||
* Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes
|
||||
* on failure
|
||||
*/
|
||||
QDF_STATUS sme_register_twt_callbacks(mac_handle_t mac_handle,
|
||||
struct twt_callbacks *twt_cb);
|
||||
|
@@ -206,6 +206,14 @@ typedef
|
||||
void (*twt_resume_dialog_cb)(struct wlan_objmgr_psoc *psoc,
|
||||
struct wmi_twt_resume_dialog_complete_event_param *params);
|
||||
|
||||
/**
|
||||
* typedef twt_notify_cb - TWT notify callback signature.
|
||||
* @psoc: Pointer to global psoc
|
||||
* @params: TWT twt notify event parameters.
|
||||
*/
|
||||
typedef
|
||||
void (*twt_notify_cb)(struct wlan_objmgr_psoc *psoc,
|
||||
struct wmi_twt_notify_event_param *params);
|
||||
/**
|
||||
* struct twt_callbacks - TWT response callback pointers
|
||||
* @twt_enable_cb: TWT enable completion callback
|
||||
@@ -214,6 +222,7 @@ void (*twt_resume_dialog_cb)(struct wlan_objmgr_psoc *psoc,
|
||||
* @twt_del_dialog_cb: TWT delete dialog completion callback
|
||||
* @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
|
||||
*/
|
||||
struct twt_callbacks {
|
||||
void (*twt_enable_cb)(hdd_handle_t hdd_handle,
|
||||
@@ -227,6 +236,8 @@ struct twt_callbacks {
|
||||
struct wmi_twt_pause_dialog_complete_event_param *params);
|
||||
void (*twt_resume_dialog_cb)(struct wlan_objmgr_psoc *psoc,
|
||||
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);
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -442,6 +453,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;
|
||||
twt_notify_cb twt_notify_cb;
|
||||
void *twt_nudge_dialog_context;
|
||||
#endif
|
||||
#ifdef FEATURE_WLAN_APF
|
||||
|
@@ -72,6 +72,7 @@
|
||||
#include "wlan_mlme_twt_api.h"
|
||||
#include "parser_api.h"
|
||||
#include <../../core/src/wlan_cm_vdev_api.h>
|
||||
#include <wlan_mlme_twt_api.h>
|
||||
|
||||
static QDF_STATUS init_sme_cmd_list(struct mac_context *mac);
|
||||
|
||||
@@ -2263,6 +2264,30 @@ sme_process_twt_resume_dialog_event(struct mac_context *mac,
|
||||
mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
|
||||
param->dialog_id, WLAN_TWT_NONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* sme_process_twt_notify_event() - Process twt ready for setup notification
|
||||
* event from firmware
|
||||
* @mac: Global MAC pointer
|
||||
* @twt_notify_event: pointer to event buf containing twt notify parameters
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
static void
|
||||
sme_process_twt_notify_event(struct mac_context *mac,
|
||||
struct wmi_twt_notify_event_param *notify_event)
|
||||
{
|
||||
twt_notify_cb callback;
|
||||
struct csr_roam_session *session;
|
||||
|
||||
session = CSR_GET_SESSION(mac, notify_event->vdev_id);
|
||||
mlme_twt_set_wait_for_notify(mac->psoc,
|
||||
&session->connectedProfile.bssid,
|
||||
FALSE);
|
||||
callback = mac->sme.twt_notify_cb;
|
||||
if (callback)
|
||||
callback(mac->psoc, notify_event);
|
||||
}
|
||||
#else
|
||||
static void
|
||||
sme_process_twt_add_dialog_event(struct mac_context *mac,
|
||||
@@ -2293,6 +2318,12 @@ sme_process_twt_nudge_dialog_event(struct mac_context *mac,
|
||||
struct wmi_twt_nudge_dialog_complete_event_param *param)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
sme_process_twt_notify_event(struct mac_context *mac,
|
||||
struct wmi_twt_notify_event_param *notify_event)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg)
|
||||
@@ -2618,6 +2649,10 @@ QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg)
|
||||
sme_process_twt_nudge_dialog_event(mac, pMsg->bodyptr);
|
||||
qdf_mem_free(pMsg->bodyptr);
|
||||
break;
|
||||
case eWNI_SME_TWT_NOTIFY_EVENT:
|
||||
sme_process_twt_notify_event(mac, pMsg->bodyptr);
|
||||
qdf_mem_free(pMsg->bodyptr);
|
||||
break;
|
||||
default:
|
||||
|
||||
if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN)
|
||||
@@ -13954,6 +13989,7 @@ QDF_STATUS sme_clear_twt_complete_cb(mac_handle_t mac_handle)
|
||||
mac->sme.twt_del_dialog_cb = NULL;
|
||||
mac->sme.twt_pause_dialog_cb = NULL;
|
||||
mac->sme.twt_resume_dialog_cb = NULL;
|
||||
mac->sme.twt_notify_cb = NULL;
|
||||
sme_release_global_lock(&mac->sme);
|
||||
|
||||
sme_debug("TWT: callbacks Initialized");
|
||||
@@ -13976,6 +14012,7 @@ QDF_STATUS sme_register_twt_callbacks(mac_handle_t mac_handle,
|
||||
mac->sme.twt_pause_dialog_cb = twt_cb->twt_pause_dialog_cb;
|
||||
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;
|
||||
sme_release_global_lock(&mac->sme);
|
||||
sme_debug("TWT: callbacks registered");
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
@@ -442,6 +442,58 @@ wma_twt_process_resume_dialog(t_wma_handle *wma_handle,
|
||||
return wmi_unified_twt_resume_dialog_cmd(wmi_handle, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* wma_twt_notify_event_handler - TWT notify event handler
|
||||
* @handle: wma handle
|
||||
* @event: buffer with event
|
||||
* @len: buffer length
|
||||
*
|
||||
* Return: 0 on success, negative value on failure
|
||||
*/
|
||||
static
|
||||
int wma_twt_notify_event_handler(void *handle, uint8_t *event, uint32_t len)
|
||||
{
|
||||
struct wmi_twt_notify_event_param *param;
|
||||
struct scheduler_msg sme_msg = {0};
|
||||
tp_wma_handle wma_handle = handle;
|
||||
wmi_unified_t wmi_handle;
|
||||
struct mac_context *mac = cds_get_context(QDF_MODULE_ID_PE);
|
||||
int status = -EINVAL;
|
||||
|
||||
if (!mac)
|
||||
return status;
|
||||
|
||||
if (wma_validate_handle(wma_handle))
|
||||
return status;
|
||||
|
||||
wmi_handle = (wmi_unified_t)wma_handle->wmi_handle;
|
||||
if (!wmi_handle) {
|
||||
wma_err("Invalid wmi handle for TWT notify event");
|
||||
return status;
|
||||
}
|
||||
|
||||
param = qdf_mem_malloc(sizeof(*param));
|
||||
if (!param)
|
||||
return -ENOMEM;
|
||||
|
||||
if (wmi_handle->ops->extract_twt_notify_event)
|
||||
status = wmi_handle->ops->extract_twt_notify_event(wmi_handle,
|
||||
event,
|
||||
param);
|
||||
wma_debug("Extract Notify event status:%d", status);
|
||||
|
||||
sme_msg.type = eWNI_SME_TWT_NOTIFY_EVENT;
|
||||
sme_msg.bodyptr = param;
|
||||
sme_msg.bodyval = 0;
|
||||
status = scheduler_post_message(QDF_MODULE_ID_WMA,
|
||||
QDF_MODULE_ID_SME,
|
||||
QDF_MODULE_ID_SME, &sme_msg);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* wma_twt_resume_dialog_complete_event_handler - TWT resume dlg complete evt
|
||||
* handler
|
||||
@@ -561,4 +613,9 @@ void wma_register_twt_events(tp_wma_handle wma_handle)
|
||||
wmi_twt_nudge_dialog_complete_event_id,
|
||||
wma_twt_nudge_dialog_complete_event_handler,
|
||||
WMA_RX_SERIALIZER_CTX);
|
||||
wmi_unified_register_event_handler
|
||||
(wma_handle->wmi_handle,
|
||||
wmi_twt_notify_event_id,
|
||||
wma_twt_notify_event_handler,
|
||||
WMA_RX_SERIALIZER_CTX);
|
||||
}
|
||||
|
Reference in New Issue
Block a user