Parcourir la source

qcacmn: Add event response for green ap low latency pwer save mode

Add low latency power save mode event response for xpan
profile.

Change-Id: If3271c8a0ed649cd04b9060060706de9ec5764c1
CRs-Fixed: 3267486
Vijay Raj il y a 2 ans
Parent
commit
2413e83ebd

+ 3 - 0
os_if/linux/wlan_cfg80211.h

@@ -270,6 +270,9 @@ enum qca_nl80211_vendor_subcmds_index {
 #ifdef CONFIG_AFC_SUPPORT
 	QCA_NL80211_VENDOR_SUBCMD_AFC_EVENT_INDEX,
 #endif
+#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
+	QCA_NL80211_VENDOR_SUBCMD_DOZED_AP_INDEX,
+#endif
 };
 
 #if !defined(SUPPORT_WDEV_CFG80211_VENDOR_EVENT_ALLOC) && \

+ 18 - 0
target_if/green_ap/inc/target_if_green_ap.h

@@ -40,6 +40,24 @@ struct wlan_green_ap_egap_params;
 QDF_STATUS target_if_register_green_ap_tx_ops(
 		struct wlan_lmac_if_tx_ops *tx_ops);
 
+#if defined(WLAN_SUPPORT_GAP_LL_PS_MODE)
+/**
+ * target_if_green_ap_register_ll_ps_event_handler() - register green ap low
+ * latency power save mode event handler
+ * @pdev: objmgr pdev
+ *
+ * Return: QDF_STATUS in case of success
+ */
+
+QDF_STATUS target_if_green_ap_register_ll_ps_event_handler(
+						struct wlan_objmgr_pdev *pdev);
+#else
+static inline QDF_STATUS target_if_green_ap_register_ll_ps_event_handler(
+						struct wlan_objmgr_pdev *pdev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif
 /**
  * target_if_green_ap_register_egap_event_handler() - registers enhanced
  *                                  green ap event handler

+ 126 - 0
target_if/green_ap/src/target_if_green_ap.c

@@ -94,6 +94,132 @@ QDF_STATUS target_if_register_green_ap_tx_ops(
 	return QDF_STATUS_SUCCESS;
 }
 
+#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
+/**
+ * target_if_green_ap_ll_ps_event() - Green AP low latency
+ * Power save event handler
+ * @scn: pointer to scn handle
+ * @evt_buf: pointer to event buffer
+ * @data_len: data len of the event buffer
+ *
+ * Return: 0 for success, otherwise appropriate error code
+ */
+static int target_if_green_ap_ll_ps_event(ol_scn_t scn, uint8_t *evt_buf,
+					  uint32_t data_len)
+{
+	QDF_STATUS status;
+	int err = 0;
+	struct wlan_objmgr_pdev *pdev;
+	struct wlan_green_ap_ll_ps_event_param *ll_ps_param;
+	void *wmi_hdl;
+	struct wlan_objmgr_psoc *psoc;
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+
+	psoc = target_if_get_psoc_from_scn_hdl(scn);
+	if (!psoc) {
+		green_ap_err("psoc is null");
+		return -ENOMEM;
+	}
+
+	pdev = target_if_get_pdev_from_scn_hdl(scn);
+	if (!pdev) {
+		green_ap_err("pdev is null");
+		return -ENOMEM;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+	if (!green_ap_ctx) {
+		green_ap_err("green_ap_ctx not found");
+		return -ENOMEM;
+	}
+
+	ll_ps_param = qdf_mem_malloc(sizeof(*ll_ps_param));
+	if (!ll_ps_param) {
+		green_ap_err("Unable to allocate memory");
+		return -ENOMEM;
+	}
+
+	qdf_mem_zero(ll_ps_param, sizeof(*ll_ps_param));
+
+	wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
+	if (!wmi_hdl) {
+		green_ap_err("null wmi_hdl");
+		err = -EINVAL;
+		goto free_event_param;
+	}
+
+	if (wmi_unified_extract_green_ap_ll_ps_param(wmi_hdl,
+						     evt_buf,
+						     ll_ps_param)) {
+		green_ap_err("unable to extract green ap ll ps event params");
+		err = -EINVAL;
+		goto free_event_param;
+	}
+
+	if ((ll_ps_param->dialog_token % 2))
+		ll_ps_param->bcn_mult = green_ap_ctx->bcn_mult;
+	else
+		ll_ps_param->bcn_mult = 1;
+
+	green_ap_debug("Next TSF: %llu Dialog Token: %llu bcn_mult: %u",
+		       ll_ps_param->next_tsf,
+		       ll_ps_param->dialog_token,
+		       ll_ps_param->bcn_mult);
+
+	status = wlan_green_ap_send_ll_ps_event_params(pdev,
+						       ll_ps_param);
+	if (status != QDF_STATUS_SUCCESS) {
+		wmi_err("wlan_green_ap_send_ll_ps_event failed");
+		err = -EINVAL;
+		goto free_event_param;
+	}
+
+free_event_param:
+	qdf_mem_free(ll_ps_param);
+	return err;
+}
+
+QDF_STATUS target_if_green_ap_register_ll_ps_event_handler(
+				struct wlan_objmgr_pdev *pdev)
+{
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+	QDF_STATUS ret;
+	wmi_unified_t wmi_hdl;
+
+	if (!pdev) {
+		green_ap_err("pdev is null");
+		return QDF_STATUS_E_INVAL;
+		}
+
+	wmi_hdl = GET_WMI_HDL_FROM_PDEV(pdev);
+	if (!wmi_hdl) {
+		green_ap_err("null wmi_hdl");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	ret = wmi_unified_register_event_handler(
+			wmi_hdl,
+			wmi_xgap_enable_complete_eventid,
+			target_if_green_ap_ll_ps_event,
+			WMI_RX_UMAC_CTX);
+
+	if (QDF_IS_STATUS_ERROR(ret))
+		green_ap_err("Failed to register Enhance Green AP event");
+	else
+		green_ap_debug("Set the Enhance Green AP event handler");
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 /**
  * target_if_green_ap_egap_status_info_event() - egap status info event
  * @scn: pointer to scn handle

+ 18 - 4
umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h

@@ -1250,7 +1250,6 @@ struct wlan_lmac_if_offchan_txrx_ops {
 };
 #endif
 
-#ifdef WLAN_SUPPORT_GREEN_AP
 struct wlan_green_ap_egap_params;
 
 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
@@ -1268,6 +1267,19 @@ struct green_ap_ll_ps_cmd_param {
 	uint16_t bcn_interval;
 	uint32_t cookie;
 };
+
+/**
+ * struct wlan_green_ap_ll_ps_event_param - Green AP low latency Power Save
+ * event parameter structure
+ * @bcn_mult: Beacon multiplier
+ * @dialog_token: Dialog token
+ * @next_rsf: Next TSF
+ */
+struct wlan_green_ap_ll_ps_event_param {
+	uint16_t bcn_mult;
+	uint32_t dialog_token;
+	uint64_t next_tsf;
+};
 #endif
 
 /**
@@ -1290,13 +1302,11 @@ struct wlan_lmac_if_green_ap_tx_ops {
 	uint16_t (*get_current_channel)(struct wlan_objmgr_pdev *pdev);
 	uint64_t (*get_current_channel_flags)(struct wlan_objmgr_pdev *pdev);
 	QDF_STATUS (*get_capab)(struct  wlan_objmgr_pdev *pdev);
-#if defined(WLAN_SUPPORT_GAP_LL_PS_MODE)
+#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
 	QDF_STATUS (*ll_ps)(struct wlan_objmgr_vdev *vdev,
 			    struct green_ap_ll_ps_cmd_param *ll_ps_params);
 #endif
-
 };
-#endif
 
 #ifdef FEATURE_COEX
 struct coex_config_params;
@@ -2425,6 +2435,10 @@ struct wlan_lmac_if_green_ap_rx_ops {
 	QDF_STATUS (*ps_get)(struct wlan_objmgr_pdev *pdev, uint8_t *value);
 	QDF_STATUS (*ps_set)(struct wlan_objmgr_pdev *pdev, uint8_t value);
 	void (*suspend_handle)(struct wlan_objmgr_pdev *pdev);
+#if defined(WLAN_SUPPORT_GAP_LL_PS_MODE)
+	QDF_STATUS (*ll_ps_cb)(struct wlan_green_ap_ll_ps_event_param
+			       *ll_ps_event_param);
+#endif
 };
 #endif
 

+ 20 - 0
umac/green_ap/core/src/wlan_green_ap_main.c

@@ -436,4 +436,24 @@ uint32_t wlan_green_ap_get_cookie_id(struct wlan_pdev_green_ap_ctx *green_ap_ctx
 
 	return id;
 }
+
+QDF_STATUS
+wlan_green_ap_send_ll_ps_event_params(struct wlan_objmgr_pdev *pdev,
+		struct wlan_green_ap_ll_ps_event_param *event_param)
+{
+	QDF_STATUS status;
+	struct wlan_pdev_green_ap_ctx *green_ap_ctx;
+
+	green_ap_ctx = wlan_objmgr_pdev_get_comp_private_obj(
+			pdev, WLAN_UMAC_COMP_GREEN_AP);
+
+	if (!green_ap_ctx) {
+		green_ap_err("green ap context obtained is NULL");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	status = green_ap_ctx->hdd_cback.send_event(green_ap_ctx->vdev, event_param);
+
+	return status;
+}
 #endif

+ 18 - 0
umac/green_ap/core/src/wlan_green_ap_main_i.h

@@ -33,6 +33,7 @@
 #include <qdf_timer.h>
 #include "wlan_utility.h"
 #include <qdf_module.h>
+#include "../../dispatcher/inc/wlan_green_ap_api.h"
 
 #define WLAN_GREEN_AP_PS_ON_TIME        (0)
 #define WLAN_GREEN_AP_PS_TRANS_TIME     (20)
@@ -126,6 +127,8 @@ enum wlan_green_ap_ll_ps_state {
  * @bcn_mult: beacon multiplier
  * @ps_en_cmd_cnt: Power save enable command count
  * @ps_dis_cmd_cnt: Power save disable command count
+ * @vdev: vdev pointer
+ * @hdd_cback: hdd callback object for green ap
  * @egap_params: Enhanced green ap params
  * @dbg_enable: Debug Enable
  */
@@ -146,6 +149,7 @@ struct wlan_pdev_green_ap_ctx {
 	qdf_atomic_t ps_en_cmd_cnt;
 	qdf_atomic_t ps_dis_cmd_cnt;
 	struct wlan_objmgr_vdev *vdev;
+	struct green_ap_hdd_callback hdd_cback;
 #endif
 	struct wlan_green_ap_egap_params egap_params;
 	bool dbg_enable;
@@ -200,6 +204,7 @@ void wlan_green_ap_check_mode(struct wlan_objmgr_pdev *pdev,
 		void *object,
 		void *arg);
 
+#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
 /**
  * wlan_green_ap_get_cookie_id() - Get Low latency Power save cookie id
  * @green_ap_ctx: green ap context
@@ -209,4 +214,17 @@ void wlan_green_ap_check_mode(struct wlan_objmgr_pdev *pdev,
  */
 uint32_t wlan_green_ap_get_cookie_id(struct wlan_pdev_green_ap_ctx *green_ap_ctx,
 				     enum wlan_green_ap_ll_ps_state state);
+
+/**
+ * wlan_green_ap_send_ll_ps_event_params() - Api to send event parameter
+ * to userspace
+ * @pdev: pdev pointer
+ * @event_param: event parameter
+ *
+ * Return: QDF_STATUS_SUCCESS on success
+ */
+QDF_STATUS wlan_green_ap_send_ll_ps_event_params(
+		struct wlan_objmgr_pdev *pdev,
+		struct wlan_green_ap_ll_ps_event_param *event_param);
+#endif
 #endif  /* _WLAN_GREEN_AP_MAIN_I_H_ */

+ 15 - 0
umac/green_ap/dispatcher/inc/wlan_green_ap_api.h

@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2022 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
@@ -26,6 +27,7 @@
 #include <wlan_objmgr_cmn.h>
 #include <wlan_objmgr_pdev_obj.h>
 #include <qdf_status.h>
+#include "../../../global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h"
 
 /* Green ap mode of operation */
 #define WLAN_GREEN_AP_MODE_NO_STA       1 /* PS if no sta connected */
@@ -61,6 +63,19 @@ struct wlan_green_ap_egap_status_info {
 	uint32_t rx_chainmask;
 };
 
+#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
+/**
+ * struct green_ap_hdd_callback: Green AP HDD callback structure
+ * @send_event: function to send the event parameter to userspace via hdd
+ */
+
+struct green_ap_hdd_callback {
+	QDF_STATUS (*send_event)(struct wlan_objmgr_vdev *vdev,
+				 struct wlan_green_ap_ll_ps_event_param *ll_event_param);
+
+};
+#endif
+
 /**
  * wlan_green_ap_init() - initialize green ap component
  *

+ 3 - 4
umac/green_ap/dispatcher/src/wlan_green_ap_ucfg_api.c

@@ -126,12 +126,11 @@ QDF_STATUS ucfg_green_ap_ll_ps(struct wlan_objmgr_pdev *pdev,
 
 	green_ap_ctx->vdev = vdev;
 	green_ap_ll_ps_params.state = state;
+	green_ap_ll_ps_params.bcn_interval = bcn_interval;
 
 	if (state)
-		green_ap_ll_ps_params.bcn_interval =
-			green_ap_ctx->bcn_mult * bcn_interval;
-	else
-		green_ap_ll_ps_params.bcn_interval = bcn_interval;
+		green_ap_ll_ps_params.bcn_interval *=
+			green_ap_ctx->bcn_mult;
 
 	green_ap_ll_ps_params.cookie =
 		wlan_green_ap_get_cookie_id(

+ 15 - 0
wmi/inc/wmi_unified_api.h

@@ -4074,6 +4074,21 @@ QDF_STATUS wmi_extract_green_ap_egap_status_info(
 	struct wlan_green_ap_egap_status_info *egap_status_info_params);
 #endif
 
+#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
+/**
+ * wmi_unified_extract_green_ap_ll_ps_param() - API to extract Green AP low
+ * latency power save event parameter
+ * @wmi_handle: wmi handle
+ * @evt_buf: pointer to the event buffer
+ * @green_ap_ll_ps_event_param: Event parameter
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS wmi_unified_extract_green_ap_ll_ps_param(
+	wmi_unified_t wmi_hdl, uint8_t *evt_buf,
+	struct wlan_green_ap_ll_ps_event_param *green_ap_ll_ps_event_param);
+#endif
+
 /**
  * wmi_unified_send_roam_scan_stats_cmd() - Wrapper to request roam scan stats
  * @wmi_handle: wmi handle

+ 3 - 0
wmi/inc/wmi_unified_param.h

@@ -5203,6 +5203,9 @@ typedef enum {
 #endif /* HEALTH_MON_SUPPORT */
 #ifdef WLAN_FEATURE_11BE_MLO
 	wmi_mlo_ap_vdev_tid_to_link_map_eventid,
+#endif
+#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
+	wmi_xgap_enable_complete_eventid,
 #endif
 	wmi_events_max,
 } wmi_conv_event_id;

+ 6 - 0
wmi/inc/wmi_unified_priv.h

@@ -555,6 +555,12 @@ QDF_STATUS (*send_green_ap_ll_ps_cmd)(wmi_unified_t wmi_handle,
 #endif
 #endif
 
+#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
+QDF_STATUS (*extract_green_ap_ll_ps_param)(
+		uint8_t *evt_buf,
+		struct wlan_green_ap_ll_ps_event_param *ll_ps_params);
+#endif
+
 QDF_STATUS
 (*send_pdev_utf_cmd)(wmi_unified_t wmi_handle,
 				struct pdev_utf_params *param,

+ 12 - 0
wmi/src/wmi_unified_api.c

@@ -280,6 +280,18 @@ QDF_STATUS wmi_unified_green_ap_ll_ps_send(
 
 	return QDF_STATUS_E_FAILURE;
 }
+
+QDF_STATUS wmi_unified_extract_green_ap_ll_ps_param(
+	wmi_unified_t wmi_handle, uint8_t *evt_buf,
+	struct wlan_green_ap_ll_ps_event_param *green_ap_ll_ps_event_param)
+{
+	if (wmi_handle->ops->extract_green_ap_ll_ps_param)
+		return wmi_handle->ops->extract_green_ap_ll_ps_param(
+				evt_buf,
+				green_ap_ll_ps_event_param);
+
+	return QDF_STATUS_E_FAILURE;
+}
 #endif
 
 QDF_STATUS

+ 38 - 0
wmi/src/wmi_unified_tlv.c

@@ -17331,6 +17331,39 @@ static QDF_STATUS extract_green_ap_egap_status_info_tlv(
 }
 #endif
 
+#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
+static QDF_STATUS extract_green_ap_ll_ps_param_tlv(
+		uint8_t *evt_buf,
+		struct wlan_green_ap_ll_ps_event_param *ll_ps_params)
+{
+	WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *param_buf;
+	wmi_xgap_enable_complete_event_fixed_param *ll_ps_event;
+
+	param_buf = (WMI_XGAP_ENABLE_COMPLETE_EVENTID_param_tlvs *)evt_buf;
+	if (!param_buf) {
+		wmi_err("Invalid XGAP SAP info status");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	ll_ps_event = (wmi_xgap_enable_complete_event_fixed_param *)
+				param_buf->fixed_param;
+	if (!ll_ps_event) {
+		wmi_err("Invalid low latency power save event buffer");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	ll_ps_params->dialog_token = ll_ps_event->dialog_token;
+	ll_ps_params->next_tsf =
+		((uint64_t)ll_ps_event->next_tsf_high32 << 32) |
+		ll_ps_event->next_tsf_low32;
+
+	wmi_debug("cookie : %llu next_tsf %llu", ll_ps_params->dialog_token,
+		  ll_ps_params->next_tsf);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
 /*
  * extract_comb_phyerr_tlv() - extract comb phy error from event
  * @wmi_handle: wmi handle
@@ -19936,6 +19969,7 @@ struct wmi_ops tlv_ops =  {
 #endif
 #ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
 	.send_green_ap_ll_ps_cmd = send_green_ap_ll_ps_cmd_tlv,
+	.extract_green_ap_ll_ps_param = extract_green_ap_ll_ps_param_tlv,
 #endif
 	.send_csa_offload_enable_cmd = send_csa_offload_enable_cmd_tlv,
 	.send_start_oem_data_cmd = send_start_oem_data_cmd_tlv,
@@ -20822,6 +20856,10 @@ static void populate_tlv_events_id(uint32_t *event_ids)
 	event_ids[wmi_extract_health_mon_init_done_info_eventid] =
 		WMI_HEALTH_MON_INIT_DONE_EVENTID;
 #endif /* HEALTH_MON_SUPPORT */
+#ifdef WLAN_SUPPORT_GAP_LL_PS_MODE
+	event_ids[wmi_xgap_enable_complete_eventid] =
+		WMI_XGAP_ENABLE_COMPLETE_EVENTID;
+#endif
 }
 
 #ifdef WLAN_FEATURE_LINK_LAYER_STATS