From 2413e83ebd720029b65c82b626195ea9796cc15e Mon Sep 17 00:00:00 2001 From: Vijay Raj Date: Wed, 30 Nov 2022 04:30:23 -0800 Subject: [PATCH] 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 --- os_if/linux/wlan_cfg80211.h | 3 + target_if/green_ap/inc/target_if_green_ap.h | 18 +++ target_if/green_ap/src/target_if_green_ap.c | 126 ++++++++++++++++++ .../lmac_if/inc/wlan_lmac_if_def.h | 22 ++- umac/green_ap/core/src/wlan_green_ap_main.c | 20 +++ umac/green_ap/core/src/wlan_green_ap_main_i.h | 18 +++ .../dispatcher/inc/wlan_green_ap_api.h | 15 +++ .../dispatcher/src/wlan_green_ap_ucfg_api.c | 7 +- wmi/inc/wmi_unified_api.h | 15 +++ wmi/inc/wmi_unified_param.h | 3 + wmi/inc/wmi_unified_priv.h | 6 + wmi/src/wmi_unified_api.c | 12 ++ wmi/src/wmi_unified_tlv.c | 38 ++++++ 13 files changed, 295 insertions(+), 8 deletions(-) diff --git a/os_if/linux/wlan_cfg80211.h b/os_if/linux/wlan_cfg80211.h index c1c393c78b..b45985caa7 100644 --- a/os_if/linux/wlan_cfg80211.h +++ b/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) && \ diff --git a/target_if/green_ap/inc/target_if_green_ap.h b/target_if/green_ap/inc/target_if_green_ap.h index a7dad833a6..cb67700e42 100644 --- a/target_if/green_ap/inc/target_if_green_ap.h +++ b/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 diff --git a/target_if/green_ap/src/target_if_green_ap.c b/target_if/green_ap/src/target_if_green_ap.c index 6bcbac232f..03131b7a9f 100644 --- a/target_if/green_ap/src/target_if_green_ap.c +++ b/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 diff --git a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h b/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h index 1ff5cc8cf2..f161f7212b 100644 --- a/umac/global_umac_dispatcher/lmac_if/inc/wlan_lmac_if_def.h +++ b/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 diff --git a/umac/green_ap/core/src/wlan_green_ap_main.c b/umac/green_ap/core/src/wlan_green_ap_main.c index f1f9908ac7..0de1a512c6 100644 --- a/umac/green_ap/core/src/wlan_green_ap_main.c +++ b/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 diff --git a/umac/green_ap/core/src/wlan_green_ap_main_i.h b/umac/green_ap/core/src/wlan_green_ap_main_i.h index d87fce83b9..8c2b7c7e3f 100644 --- a/umac/green_ap/core/src/wlan_green_ap_main_i.h +++ b/umac/green_ap/core/src/wlan_green_ap_main_i.h @@ -33,6 +33,7 @@ #include #include "wlan_utility.h" #include +#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_ */ diff --git a/umac/green_ap/dispatcher/inc/wlan_green_ap_api.h b/umac/green_ap/dispatcher/inc/wlan_green_ap_api.h index 27b86fd9cb..b0d2790690 100644 --- a/umac/green_ap/dispatcher/inc/wlan_green_ap_api.h +++ b/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 #include #include +#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 * diff --git a/umac/green_ap/dispatcher/src/wlan_green_ap_ucfg_api.c b/umac/green_ap/dispatcher/src/wlan_green_ap_ucfg_api.c index 7285046182..a9eed92a87 100644 --- a/umac/green_ap/dispatcher/src/wlan_green_ap_ucfg_api.c +++ b/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( diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index b79d0f9e58..bc3cdc023f 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/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 diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index ba0739f1f2..2c39c9dbfc 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/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; diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 4fe811d4c5..5da778c74f 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/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, diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index 9ea29a669c..98e71dd14f 100644 --- a/wmi/src/wmi_unified_api.c +++ b/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 diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index f19af40324..e6d217b48e 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/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