浏览代码

qcacmn: Register pmo handler for twt

Register pmo handler for twt to prevent WMI from
crashing due to concurrent WMI_WOW_ENABLE_CMDID
and twt requester enable commands during suspend.

Change-Id: Ifeef52f7a758020e8599a056f9b3f03455e96def
CRs-Fixed: 3580088
Aasir Rasheed 1 年之前
父节点
当前提交
0cd3985fb6

+ 36 - 1
umac/twt/core/src/wlan_twt_objmgr.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. 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
@@ -37,6 +37,7 @@ wlan_twt_psoc_obj_create_handler(struct wlan_objmgr_psoc *psoc, void *arg)
 
 	twt_psoc_obj->enable_context.context = NULL;
 	twt_psoc_obj->disable_context.context = NULL;
+	twt_psoc_obj->twt_pmo_disabled = 0;
 
 	status = wlan_objmgr_psoc_component_obj_attach(psoc,
 						       WLAN_UMAC_COMP_TWT,
@@ -207,3 +208,37 @@ wlan_twt_peer_obj_destroy_handler(struct wlan_objmgr_peer *peer, void *arg)
 	return QDF_STATUS_SUCCESS;
 }
 
+QDF_STATUS
+wlan_twt_psoc_set_pmo_disable(struct wlan_objmgr_psoc *psoc,
+			      enum twt_disable_reason reason)
+{
+	struct twt_psoc_priv_obj *twt_psoc_obj;
+
+	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
+	if (!twt_psoc_obj) {
+		twt_err("twt_psoc_obj is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	twt_psoc_obj->twt_pmo_disabled |= reason;
+	twt_debug("Psoc twt_disabled %x", twt_psoc_obj->twt_pmo_disabled);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+QDF_STATUS
+wlan_twt_psoc_set_pmo_enable(struct wlan_objmgr_psoc *psoc,
+			     enum twt_disable_reason reason)
+{
+	struct twt_psoc_priv_obj *twt_psoc_obj;
+
+	twt_psoc_obj = wlan_twt_psoc_get_comp_private_obj(psoc);
+	if (!twt_psoc_obj) {
+		twt_err("twt_psoc_obj is NULL");
+		return QDF_STATUS_E_INVAL;
+	}
+	twt_psoc_obj->twt_pmo_disabled &= ~reason;
+	twt_debug("Psoc twt_disabled %x", twt_psoc_obj->twt_pmo_disabled);
+
+	return QDF_STATUS_SUCCESS;
+}
+

+ 2 - 0
umac/twt/core/src/wlan_twt_priv.h

@@ -62,12 +62,14 @@ struct twt_tgt_caps {
  * @twt_caps: twt caps
  * @enable_context: enable context
  * @disable_context: disable context
+ * @twt_pmo_disabled: twt pmo disabled
  */
 struct twt_psoc_priv_obj {
 	psoc_twt_ext_cfg_params_t cfg_params;
 	struct twt_tgt_caps twt_caps;
 	struct twt_en_dis_context enable_context;
 	struct twt_en_dis_context disable_context;
+	uint32_t twt_pmo_disabled;
 };
 
 /**

+ 29 - 0
umac/twt/dispatcher/inc/wlan_twt_api.h

@@ -25,6 +25,7 @@
 #include <wlan_objmgr_psoc_obj.h>
 #include <wlan_objmgr_global_obj.h>
 #include <wlan_lmac_if_def.h>
+#include <wlan_twt_public_structs.h>
 
 #define twt_alert(params...) \
 	QDF_TRACE_FATAL(QDF_MODULE_ID_TWT, params)
@@ -118,6 +119,26 @@ QDF_STATUS
 wlan_set_peer_twt_capabilities(struct wlan_objmgr_psoc *psoc,
 			       struct qdf_mac_addr *peer_mac,
 			       uint8_t peer_cap);
+/**
+ * wlan_twt_psoc_set_pmo_enable() - twt psoc set enable
+ * @psoc: psoc handle
+ * @reason: twt enable reason
+ *
+ * return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_twt_psoc_set_pmo_enable(struct wlan_objmgr_psoc *psoc,
+			     enum twt_disable_reason reason);
+/**
+ * wlan_twt_psoc_set_pmo_disable() - twt psoc set disable
+ * @psoc: psoc handle
+ * @reason: twt disable reason
+ *
+ *  return: QDF_STATUS
+ */
+QDF_STATUS
+wlan_twt_psoc_set_pmo_disable(struct wlan_objmgr_psoc *psoc,
+			      enum twt_disable_reason reason);
 
 #else
 static inline
@@ -151,5 +172,13 @@ QDF_STATUS wlan_set_peer_twt_capabilities(struct wlan_objmgr_psoc *psoc,
 {
 	return QDF_STATUS_SUCCESS;
 }
+
+QDF_STATUS
+wlan_twt_psoc_set_pmo_enable(struct wlan_objmgr_psoc *psoc,
+			     enum twt_disable_reason reason);
+
+QDF_STATUS
+wlan_twt_psoc_set_pmo_disable(struct wlan_objmgr_psoc *psoc,
+			      enum twt_disable_reason reason);
 #endif
 #endif /* _WLAN_TWT_API_H_ */

+ 8 - 0
umac/twt/dispatcher/inc/wlan_twt_public_structs.h

@@ -1061,5 +1061,13 @@ enum twt_traffic_ac {
 	TWT_AC_MAX = 4,
 };
 
+/**
+ * enum twt_disable_reason - twt disable/enable reason
+ * @REASON_PMO_SUSPEND: reason is suspended
+ */
+enum twt_disable_reason {
+	REASON_PMO_SUSPEND  = 0x1,
+};
+
 #endif /* _WLAN_TWT_PUBLIC_STRUCTS_H_ */
 

+ 1 - 0
umac/twt/dispatcher/inc/wlan_twt_ucfg_ext_cfg.h

@@ -115,6 +115,7 @@ ucfg_twt_cfg_get_rtwt_requestor(struct wlan_objmgr_psoc *psoc, bool *val);
  */
 QDF_STATUS
 ucfg_twt_cfg_get_flex_sched(struct wlan_objmgr_psoc *psoc, bool *val);
+
 #else
 static inline
 QDF_STATUS ucfg_twt_cfg_get_requestor(struct wlan_objmgr_psoc *psoc, bool *val)

+ 54 - 0
umac/twt/dispatcher/src/wlan_twt_api.c

@@ -22,6 +22,9 @@
 #include <wlan_twt_api.h>
 #include "twt/core/src/wlan_twt_objmgr_handler.h"
 #include "twt/core/src/wlan_twt_common.h"
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+#include <wlan_pmo_obj_mgmt_api.h>
+#endif
 
 struct wlan_lmac_if_twt_tx_ops *
 wlan_twt_get_tx_ops(struct wlan_objmgr_psoc *psoc)
@@ -66,6 +69,52 @@ wlan_twt_psoc_get_comp_private_obj(struct wlan_objmgr_psoc *psoc)
 	return twt_psoc;
 }
 
+#ifdef WLAN_POWER_MANAGEMENT_OFFLOAD
+static QDF_STATUS
+wlan_twt_suspend_handler(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	wlan_twt_psoc_set_pmo_disable(psoc, REASON_PMO_SUSPEND);
+	return QDF_STATUS_SUCCESS;
+}
+
+static QDF_STATUS
+wlan_twt_resume_handler(struct wlan_objmgr_psoc *psoc, void *arg)
+{
+	wlan_twt_psoc_set_pmo_enable(psoc, REASON_PMO_SUSPEND);
+	return QDF_STATUS_SUCCESS;
+}
+
+static void
+wlan_twt_register_pmo_handler(void)
+{
+	pmo_register_suspend_handler(WLAN_UMAC_COMP_TWT,
+				     wlan_twt_suspend_handler, NULL);
+	pmo_register_resume_handler(WLAN_UMAC_COMP_TWT,
+				    wlan_twt_resume_handler, NULL);
+}
+
+static inline void
+wlan_twt_unregister_pmo_handler(void)
+{
+	pmo_unregister_suspend_handler(WLAN_UMAC_COMP_TWT,
+				       wlan_twt_suspend_handler);
+	pmo_unregister_resume_handler(WLAN_UMAC_COMP_TWT,
+				      wlan_twt_resume_handler);
+}
+
+#else
+static void
+wlan_twt_register_pmo_handler(void)
+{
+}
+
+static inline void
+wlan_twt_unregister_pmo_handler(void)
+{
+}
+
+#endif
+
 QDF_STATUS wlan_twt_init(void)
 {
 	QDF_STATUS status = QDF_STATUS_E_FAILURE;
@@ -219,6 +268,8 @@ QDF_STATUS twt_psoc_enable(struct wlan_objmgr_psoc *psoc)
 	if (QDF_IS_STATUS_ERROR(status))
 		twt_err("twt_register_events failed (status=%d)", status);
 
+	wlan_twt_register_pmo_handler();
+
 	return status;
 }
 
@@ -238,6 +289,8 @@ QDF_STATUS twt_psoc_disable(struct wlan_objmgr_psoc *psoc)
 		twt_err("twt_deregister_events failed (status=%d)",
 			status);
 
+	wlan_twt_unregister_pmo_handler();
+
 	return status;
 }
 
@@ -248,3 +301,4 @@ wlan_set_peer_twt_capabilities(struct wlan_objmgr_psoc *psoc,
 {
 	return wlan_twt_set_peer_capabilities(psoc, peer_mac, peer_cap);
 }
+