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;
|
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
|
* hdd_twt_configure - Process the TWT
|
||||||
* operation in the received vendor command
|
* 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_del_dialog_cb = hdd_twt_del_dialog_comp_cb;
|
||||||
twt_cb.twt_pause_dialog_cb = hdd_twt_pause_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_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);
|
status = sme_register_twt_callbacks(hdd_ctx->mac_handle, &twt_cb);
|
||||||
if (QDF_IS_STATUS_ERROR(status)) {
|
if (QDF_IS_STATUS_ERROR(status)) {
|
||||||
hdd_err("Register twt enable complete failed");
|
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
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
* any purpose with or without fee is hereby granted, provided that the
|
* 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_PAUSE_DIALOG_EVENT = SIR_SME_MSG_TYPES_BEGIN + 167,
|
||||||
eWNI_SME_TWT_RESUME_DIALOG_EVENT = SIR_SME_MSG_TYPES_BEGIN + 168,
|
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_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 {
|
typedef struct sAniCfgTxRateCtrs {
|
||||||
|
@@ -3675,7 +3675,8 @@ QDF_STATUS sme_clear_twt_complete_cb(mac_handle_t mac_handle);
|
|||||||
* @mac_handle: MAC handle
|
* @mac_handle: MAC handle
|
||||||
* @twt_cb: TWT callbacks
|
* @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,
|
QDF_STATUS sme_register_twt_callbacks(mac_handle_t mac_handle,
|
||||||
struct twt_callbacks *twt_cb);
|
struct twt_callbacks *twt_cb);
|
||||||
|
@@ -207,13 +207,22 @@ void (*twt_resume_dialog_cb)(struct wlan_objmgr_psoc *psoc,
|
|||||||
struct wmi_twt_resume_dialog_complete_event_param *params);
|
struct wmi_twt_resume_dialog_complete_event_param *params);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct twt_callbacks - TWT response callback pointers
|
* 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
|
* @twt_enable_cb: TWT enable completion callback
|
||||||
* @twt_disable_cb: TWT disable completion callback
|
* @twt_disable_cb: TWT disable completion callback
|
||||||
* @twt_add_dialog_cb: TWT add dialog completion callback
|
* @twt_add_dialog_cb: TWT add dialog completion callback
|
||||||
* @twt_del_dialog_cb: TWT delete dialog completion callback
|
* @twt_del_dialog_cb: TWT delete dialog completion callback
|
||||||
* @twt_pause_dialog_cb: TWT pause dialog completion callback
|
* @twt_pause_dialog_cb: TWT pause dialog completion callback
|
||||||
* @twt_resume_dialog_cb: TWT resume dialog completion callback
|
* @twt_resume_dialog_cb: TWT resume dialog completion callback
|
||||||
|
* @twt_notify_cb: TWT notify event callback
|
||||||
*/
|
*/
|
||||||
struct twt_callbacks {
|
struct twt_callbacks {
|
||||||
void (*twt_enable_cb)(hdd_handle_t hdd_handle,
|
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);
|
struct wmi_twt_pause_dialog_complete_event_param *params);
|
||||||
void (*twt_resume_dialog_cb)(struct wlan_objmgr_psoc *psoc,
|
void (*twt_resume_dialog_cb)(struct wlan_objmgr_psoc *psoc,
|
||||||
struct wmi_twt_resume_dialog_complete_event_param *params);
|
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
|
#endif
|
||||||
|
|
||||||
@@ -442,6 +453,7 @@ struct sme_context {
|
|||||||
twt_pause_dialog_cb twt_pause_dialog_cb;
|
twt_pause_dialog_cb twt_pause_dialog_cb;
|
||||||
twt_nudge_dialog_cb twt_nudge_dialog_cb;
|
twt_nudge_dialog_cb twt_nudge_dialog_cb;
|
||||||
twt_resume_dialog_cb twt_resume_dialog_cb;
|
twt_resume_dialog_cb twt_resume_dialog_cb;
|
||||||
|
twt_notify_cb twt_notify_cb;
|
||||||
void *twt_nudge_dialog_context;
|
void *twt_nudge_dialog_context;
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEATURE_WLAN_APF
|
#ifdef FEATURE_WLAN_APF
|
||||||
|
@@ -72,6 +72,7 @@
|
|||||||
#include "wlan_mlme_twt_api.h"
|
#include "wlan_mlme_twt_api.h"
|
||||||
#include "parser_api.h"
|
#include "parser_api.h"
|
||||||
#include <../../core/src/wlan_cm_vdev_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);
|
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,
|
mac->psoc, (struct qdf_mac_addr *)param->peer_macaddr,
|
||||||
param->dialog_id, WLAN_TWT_NONE);
|
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
|
#else
|
||||||
static void
|
static void
|
||||||
sme_process_twt_add_dialog_event(struct mac_context *mac,
|
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)
|
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
|
#endif
|
||||||
|
|
||||||
QDF_STATUS sme_process_msg(struct mac_context *mac, struct scheduler_msg *pMsg)
|
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);
|
sme_process_twt_nudge_dialog_event(mac, pMsg->bodyptr);
|
||||||
qdf_mem_free(pMsg->bodyptr);
|
qdf_mem_free(pMsg->bodyptr);
|
||||||
break;
|
break;
|
||||||
|
case eWNI_SME_TWT_NOTIFY_EVENT:
|
||||||
|
sme_process_twt_notify_event(mac, pMsg->bodyptr);
|
||||||
|
qdf_mem_free(pMsg->bodyptr);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
||||||
if ((pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN)
|
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_del_dialog_cb = NULL;
|
||||||
mac->sme.twt_pause_dialog_cb = NULL;
|
mac->sme.twt_pause_dialog_cb = NULL;
|
||||||
mac->sme.twt_resume_dialog_cb = NULL;
|
mac->sme.twt_resume_dialog_cb = NULL;
|
||||||
|
mac->sme.twt_notify_cb = NULL;
|
||||||
sme_release_global_lock(&mac->sme);
|
sme_release_global_lock(&mac->sme);
|
||||||
|
|
||||||
sme_debug("TWT: callbacks Initialized");
|
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_pause_dialog_cb = twt_cb->twt_pause_dialog_cb;
|
||||||
mac->sme.twt_resume_dialog_cb = twt_cb->twt_resume_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_disable_cb = twt_cb->twt_disable_cb;
|
||||||
|
mac->sme.twt_notify_cb = twt_cb->twt_notify_cb;
|
||||||
sme_release_global_lock(&mac->sme);
|
sme_release_global_lock(&mac->sme);
|
||||||
sme_debug("TWT: callbacks registered");
|
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
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
* any purpose with or without fee is hereby granted, provided that the
|
* 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);
|
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
|
* wma_twt_resume_dialog_complete_event_handler - TWT resume dlg complete evt
|
||||||
* handler
|
* handler
|
||||||
@@ -561,4 +613,9 @@ void wma_register_twt_events(tp_wma_handle wma_handle)
|
|||||||
wmi_twt_nudge_dialog_complete_event_id,
|
wmi_twt_nudge_dialog_complete_event_id,
|
||||||
wma_twt_nudge_dialog_complete_event_handler,
|
wma_twt_nudge_dialog_complete_event_handler,
|
||||||
WMA_RX_SERIALIZER_CTX);
|
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